赞
踩
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
带头结点的单链表和不带头结点的单链表
一、两者区别:
1、不带头结点的单链表对于第一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常在单链表的开始结点之前附设一个头结点。
2、带头结点的单链表,初始时一定返回的是指向头结点的地址,所以一定要用二维指针,否则将导致内存访问失败或异常。
3、带头结点与不带头结点初始化、插入、删除、输出操作都不样,在遍历输出链表数据时,带头结点的判断条件是while(head->next!=NULL),而不带头结点是while(head!=NULL),虽然头指针可以在初始时设定,但是如1所述,对于特殊情况如只有一个节点会出现问题。
这里定义一个英雄,相当于节点,节点中指向下一个节点,英雄中存在下一个英雄。
- class HeroNode {
-
- public int no;
- public String name;
- public String nickname;
- public HeroNode next;
-
- // 构造器
- public HeroNode(int no, String name, String nickname) {
- this.no = no;
- this.name = name;
- this.nickname = nickname;
- }
-
- @Override
- public String toString() {
- return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
- }
-
- }
- // 定义一个SingleLinkedList管理英雄人物
- class SingleLinkedList {
-
- // 先初始化一个头结点 头结点不要动
- private HeroNode head = new HeroNode(0, "", "");
-
- // 添加方法 添加到链表的最后
- // 不考虑编号的顺序时,找到当前链表中下一个next为null的英雄则为最后一个英雄
- // 将最后英雄的next指向新节点
- public void add(HeroNode heroNode) {
- // head节点不能动,因此我们需要一个辅助变量
- // temp相当于指针,遍历每个变量
- HeroNode temp = head;
- while (true) {
- // 什么时候说明链表到最后了就结束
- if (temp.next == null) {
- break;
- }
- // 如果不是最后一个就后移
- temp = temp.next;
- } // 只有temp指向最后一个的时候 才会退出循环
- // 让最后一个元素的下一个指向新添加的元素结束
- temp.next = heroNode;
- }
-
- // 第二种方式添加 根据序号添加
- // 如果排名存在则显示添加失败,并给出提示
- public void addByOrder(HeroNode heroNode) {
- // head节点不能动,因此我们需要一个辅助变量
- // 因为单链表 因此我们找的temp是添加位置的前一个节点 否则插入不了
- HeroNode temp = head;
- boolean flag = false;
- // 标志添加的节点编号是否存在,默认为false
- // break会跳出循环
- while (true) {
- if (temp.next == null) {
- // 说明temp已经在链表的最后
- break;
- }
- // 下一个节点的序号是否比需要添加的节点大
- if (temp.next.no > heroNode.no) {
- break;
- } else if (temp.next.no == heroNode.no) {
- flag = true;// 说明编号存在
- break;
- }
- // 往后找出当前节点的下一个节点比需要添加的节点大的节点
- temp = temp.next;
- }
- // 判断flag的值 如果为true 证明编号存在了
- if (flag) {
- System.out.println("编号存在,不能加入");
- } else {
- heroNode.next = temp.next;
- temp.next = heroNode;
- }
-
- }
- // 显示链表[遍历]
- public void list() {
- // 通过辅助变量 遍历链表
- HeroNode temp = head;
- while (true) {
- // 头结点不能动 辅助变量来遍历
- // 判断链表到最后结束
- if (temp.next == null) {
- break;
- }
- System.out.println(temp.next);
- temp = temp.next;
- }
-
- }
- // 根据heroNode的no节点来修改
- public void update(HeroNode heroNode) {
- // 判断链表是否是空的
- if (head.next == null) {
- System.out.println("链表是空的");
- return;
- }
- // 找到需要修改的节点,根据no找
- // 定义辅助变量查找
- HeroNode temp = head;
- boolean flag = false;
- while (true) {
- if (temp.no == heroNode.no) {
- //找到了
- flag = true;
- break;
- }
- if (temp.next == null) {
- // 链表遍历结束
- break;
- }
-
- temp = temp.next;
- }
- //找到了就修改
- if(flag) {
- temp.name=heroNode.name;
- temp.nickname=heroNode.nickname;
- }else {
- //flag仍然等于false 表示没有找到这个节点
- System.out.println("没有找到编号等于这个的节点"+heroNode.no);
- }
-
- }
- //删除节点 找到需要删除的节点的前一个节点
- //被删除的节点没有任何引用 会被垃圾回收机制回收
- public void delete(int no) {
- // 通过辅助变量 遍历链表
- HeroNode temp = head;
- //是否找到需要删除的
- boolean flag = false;
- while(true){
- if (temp.next==null) {
- break;
- }
- if(temp.next.no==no) {
- //找到了待删除节点的前一个节点
- flag = true;
- break;
- }
- temp=temp.next;
- }
- if(flag) {
- //找到了可以删除
- temp.next=temp.next.next;
- }else {
- System.out.println("没有找到待删除的节点");
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。