单链表

单链表(其一)

单向链表的创建和添加

背景

  • 数据结构——单向链表

  • 博主以b站尚硅谷Java数据结构与算法课进行学习

概念

  • 链表:
    • 链表以节点的方式进行存储
    • 每个节点包含data域next域
      • next域指向下一节点
    • 链表的各个节点不一点按顺序存储
    • 链表分带头节点和没有带头节点的链表

问题

  • 使用带head头的单向链表实现–水浒传排行榜管理
    • 完成对人物的增删改查
    • 第一种方法在添加人物时,直接添加到链表的尾部
    • 第二种方法在添加人物时,根据排名将人物插入到指点位置(如果有这个排名则添加失败,并给出提示)

思路分析

  • 相关数据

    • int no,String name,String nickName ,HeroNode next
    • head节点
      • 不存放具体的数据
      • 作用就是表示单链表头
      • next–指向下个节点
    • HeroNode节点
      • 数据
      • next域
  • 不需要按照编号顺序添加(创建)

    • 先创建一个head头节点,作用就是表示单链表的头
    • 后面我们添加每一个节点,就直接加入到链表的最后
  • 遍历

    • 通过一个辅助遍历,帮助遍历整个链表
  • 需要按照编号顺序添加

    • 首先找到新添加节点的位置,通过**辅助变量(temp)**找到

    • 新的节点. next = temp.next

    • 将temp.next = 新的节点

步骤

  • 定义一个HeroNode类,每个HeroNode对象就是一个节点

    • 相关属性

      • int no,String name,String nickname HeroNode next;
    • 代码实现

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      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;
      }
      //为了显示方便,重写toString方法
      @Override
      public String toString() {
      return "HeroNode{" +
      "no=" + no +
      ", name='" + name + '\'' +
      ", nickname='" + nickname + '\'' +
      '}';
      }
      }
  • 定义一个SingleLinkedList类------管理我们的人物

  • 第一种方法,直接添加数据到尾部

    • 先初始化一个头节点,头节点不能动,不能存放数据

      • 代码实现

        1
        private  HeroNode head = new HeroNode(0,"","");
    • 当不考虑编号顺序时,先找到当前链表的最后节点,将最后节点next指向新的节点,因为head头节点不能动,所以需要辅助便利temp遍历

      • 代码实现

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        public void add(HeroNode heroNode){
        //当不考虑编号顺序时
        //先找到当前链表的最后节点
        //将最后节点next指向新的节点
        //因为head头节点不能动,所以需要辅助遍历temp
        HeroNode temp = head;
        //遍历链表找到最后
        while(true){
        //代表找到链表的最后
        if(temp.next==null){
        break;
        }
        //找不到就将temp后移,直至找到后退出循环
        temp = temp.next;
        }
        //当退出循环时,temp指向链表的最后
        //将这个节点的next指向新节点
        temp.next = heroNode;
        }
  • 第二种方法,按照顺序添加人物插入链表

    • 先初始化一个头节点,头节点不能动,不能存放数据

      • 代码实现

        1
        private  HeroNode head = new HeroNode(0,"","");
    • 头节点不能动,所以我们需要一个辅助变量temp来寻找添加的位置,因为是单链表,我们找的temp是位于添加位置的前一个节点,否则插入不了

      • 代码实现

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
         public void addByOrder(HeroNode heroNode){
        //头节点不能动,所以我们需要一个辅助变量来寻找添加的位置
        //因为是单链表,我们找的temp是位于添加位置的前一个节点,否则插入不了
        HeroNode temp = head;
        boolean flag = false;//flag标志添加的符号是否存在,默认为false
        while(true){
        if(temp.next==null){//表示已经找到链表的最后
        break;
        }
        if(temp.next.no> heroNode.no){//位置找到,就是temp的后面插入
        break;

        }else if(temp.next.no ==heroNode.no){//编号存在
        flag = true;
        break;
        }
        temp = temp.next;//后移,遍历当前的链表
        }
        //判断flag的值
        if(flag){//不能添加,编号存在
        System.out.println("存在"+heroNode.no);
        }else{
        //插入链表中,temp的后面
        heroNode.next = temp.next;
        temp.next = heroNode;
        }
        }
  • 显示链表List方法

    • 先判断链表是否为空,同时需要辅助变量

      • 代码实现

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
              
        //显示链表
        public void list(){
        //判断链表是否为空
        if(head.next==null){
        System.out.println("链表为空");
        return;
        }
        //因为头节点不能动,所以需要辅助变量遍历
        HeroNode temp = head.next;
        while(true){
        //判断链表是否最后
        if(temp==null){
        break;
        }
        //输出节点的信息
        System.out.println(temp);
        //将节点后移
        temp = temp.next;
        }
        }
  • 主类SingLinkedListDemo:测试

    • 代码实现

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      public class SingLinkedListDemo {
      public static void main(String[] args) {
      //测试
      HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");
      HeroNode heroNode2 = new HeroNode(2,"卢俊义","玉麒麟");
      HeroNode heroNode3 = new HeroNode(3,"吴用","智多星");
      HeroNode heroNode4 = new HeroNode(4,"林冲","豹子头");
      //创建链表
      SingleLinkedList singleLinkedList = new SingleLinkedList();
      //第一种方法加入
      /* singleLinkedList.add(heroNode1);
      singleLinkedList.add(heroNode4);
      singleLinkedList.add(heroNode3);
      singleLinkedList.add(heroNode2);*/
      //第二种方法加入,按照顺序加入
      System.out.println("===================================");
      singleLinkedList.addByOrder(heroNode1);
      singleLinkedList.addByOrder(heroNode4);
      singleLinkedList.addByOrder(heroNode3);
      singleLinkedList.addByOrder(heroNode2);
      singleLinkedList.list();
      }
      }

运行结果图

  • 第一种方法

  • 第二种方法