首页 > 其他 > 详细

04-单链表

时间:2020-01-19 17:38:34      阅读:69      评论:0      收藏:0      [点我收藏+]

1. 简单介绍

技术分享图片

  • 链表是一组任意的存储单元,通过指针链接,串成一个链子

  • 数据元素的存储映象,称为 [结点],由两部分构成
    • 数据域:用来存储数据
    • 指针域:存储后继结点的地址
  • 专业术语
    • 头结点:数据域不存储信息;指针域存储 [首结点] 的地址
    • 首结点:第一个存放有效数据的结点
    • 尾结点:最后一个存放有效数据的结点

2. 链表的分类

技术分享图片

3. 单链表代码实现

  • 添加结点
    技术分享图片
  • 按编号顺序添加结点
    技术分享图片
  • 删除结点
    技术分享图片
public class SingleLinkedList {
    // 先初始化 [头结点], 头结点不存放数据
    private HeroNode head = new HeroNode(0,"","");
    
    public HeroNode getHead() {
        return head;
    }

    // 添加结点到单链表(不考虑编号顺序)
    public void add(HeroNode node) {
        // 1. 找到 [尾结点], 将 其尾结点的next域 指向 {要添加的结点}
        // 1.1 定义一个临时变量, 用来指向链表当前遍历到的元素
        HeroNode temp = head;
        // 1.2 遍历:当退出while循环时, temp此时指向的是尾结点
        while(temp.next != null)
            temp = temp.next;
        // 2. 将新节点的地址赋值给尾结点的指针域
        temp.next = node;
    }
    
    // 根据排名将结点插入指定位置(如果有这个排名, 则添加失败, 并给出提示)
    public void insertByOrder(HeroNode node) {
        // 1. 找到 新结点 要插入的位置(遍历 + 辅助变量)
        // 因为是单链表, 所以temp最终应指向 新结点要放置位置的前一个结点
        HeroNode temp = head;
        // 用来标识新结点的编号是否已存在
        boolean flag = false;
        
        // 循环终止时, temp指向链表尾结点
        while(temp.next != null) { 
            if(temp.next.no > node.no) { // find it! 
                break;
            } else if(temp.next.no == node.no) { // 说明编号已存在
                flag = true;
                break;
            }
            temp = temp.next; // 后移
        }

        if(!flag) { // 2. 新结点应插入到 temp 和 temp.next 之间
            node.next = temp.next;
            temp.next = node;
        } else { // 不能加入, 编号已存在
            System.out.printf("编号%d已存在, 不能插入\n", node.no);
        }
    }
    
    // 根据编号修改结点数据
    public void updateByNo(HeroNode node) {
        // 判断链表是否空
        if(head.next == null) 
            System.out.println("链表为空");
        // 找到需要修改的结点
        HeroNode temp = head.next;
        // 是否找到该结点
        boolean flag = false; 
        while(temp.next != null) {
            if(temp.no == node.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 根据 flag 是否找到要修改的结点
        if(flag) {
            temp.name = node.name;
            temp.nickname = node.nickname;
        } else 
            System.out.printf("不存在编号为%d的结点\n", node.no);
    }
    
    // 删除结点
    public void deleteNode(int no) {
        // 判断链表是否空
        if(head.next == null) {
            System.out.println("链表为空");
            return;
        }
        // 找到 待删除结点 的前一个结点temp
        HeroNode temp = head;
        boolean flag = false;
        while(temp.next != null) {
            if(temp.next.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag) {
            // 待删除结点因没有任何引用指向, 故会被垃圾回收机制回收
            temp.next = temp.next.next;
        } else 
            System.out.printf("不存在编号为%d的结点\n", no);
    }

    // 打印链表(遍历)
    public void showList() {
        if(head.next == null) {
            System.out.println("链表为空");
            return;
        }
        
        // 头结点不能动, 故需要一个临时变量来遍历
        HeroNode temp = head.next;
        while(temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }
}

// 定义HeroNode, 每个HeroNode对象就是一个结点
class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;
    
    public HeroNode(int no, String name, String nickname) {
        super();
        this.no = no;
        this.name = name;
        this.nickname = nickname;
        this.next = null;
    }

    @Override
    public String toString() {
        return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
    }
    
}

04-单链表

原文:https://www.cnblogs.com/liujiaqi1101/p/12214444.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!