• 单链表


    单链表

      单链表(带头链表)的逻辑结构示意图

      

      单链表的应用实例

        使用带 head 头的单向链表实现:对水浒英雄排行榜管理,完成对英雄人物的增删改查操作。

        (1)第一种方法添加英雄时,直接添加到链表的尾部。

          思路分析示意图:

        (2)第二种方式添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)

          思路示意图:

        

        (3)修改节点功能

          思路分析:

            ① 先找到该节点,通过遍历

            ② temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; 

        (4)删除节点功能

          思路分析:

        (5)代码实现

      1 public class SingleLinkedListDemo {
      2 
      3     public static void main(String[] args) {
      4         // 测试
      5         // 先创建节点
      6         HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
      7         HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
      8         HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
      9         HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
     10 
     11         // 创建链表
     12         SingleLinkedList list = new SingleLinkedList();
     13 
     14         // 加入
     15         list.add(hero1);
     16         list.add(hero2);
     17         list.add(hero3);
     18         list.add(hero4);
     19 
     20         // 显示
     21         list.list();
     22 
     23         // 修改
     24         HeroNode heroNode = new HeroNode(2, "小卢", "玉麒麟~~");
     25         list.update(heroNode);
     26 
     27         System.out.println("修改后的链表-----");
     28         list.list();
     29 
     30         // 删除节点
     31         list.del(1);
     32         System.out.println("删除后的链表-----");
     33         list.list();
     34 
     35     }
     36 
     37 }
     38 
     39 // 定义 SingleLinkedList ,管理英雄
     40 class SingleLinkedList {
     41     // 先初始化一个头节点,头节点不要动,不存放具体的数据
     42     private HeroNode head = new HeroNode(0, "", "");
     43 
     44     // 添加节点到单向链表
     45     // 当不考虑编号顺序时,
     46     // 1.找到当前链表的最后节点
     47     // 2.将最后这个节点的 next 指向新的节点
     48     public void add(HeroNode heroNode) {
     49 
     50         // 因为head节点不能动,因此我们需要一个辅助指针 temp
     51         HeroNode temp = head;
     52         // 遍历
     53         while (true) {
     54             // 找到链表的最后
     55             if (temp.next == null) {
     56                 break;
     57             }
     58             // 如果没有找到最后,将 temp 后移
     59             temp = temp.next;
     60         }
     61 
     62         // 当退出 while 循环时,temp 就执行了链表的最后
     63         // 将最后这个节点的 next指向新的节点
     64         temp.next = heroNode;
     65     }
     66 
     67     // 修改节点的信息,根据 no 编号来修改,即no编号不能改
     68     // 根据newHeroNode 的 no 来修改即可
     69     public void update(HeroNode newHeroNode) {
     70         // 判断是否为空
     71         if (head.next == null) {
     72             System.out.println("链表为空");
     73             return;
     74         }
     75         // 找到需要修改的节点,根据 no 编号
     76         // 定义一个辅助变量
     77         HeroNode temp = head.next;
     78         boolean flag = false; // 表示是否找到该节点
     79         while (true) {
     80             if (temp == null) {
     81                 break; // 已经遍历完
     82             }
     83             if (temp.no == newHeroNode.no) {
     84                 flag = true;
     85                 break;
     86             }
     87 
     88             temp = temp.next;
     89         }
     90 
     91         // 根据 flag,判断是否找到要修改的节点
     92         if (flag) {
     93             temp.name = newHeroNode.name;
     94             temp.nickname = newHeroNode.nickname;
     95         } else {
     96             System.out.printf("没有找到编号%d的节点,不能修改\n", newHeroNode.no);
     97         }
     98     }
     99 
    100     // 删除节点
    101     // head 不能动,需要一个辅助节点,找到待删除节点的前一个节点
    102     // 比较时,就是 temp.next.no 和需要删除的节点 no 比较
    103     public void del(int no) {
    104         HeroNode temp = head;
    105         boolean flag = false; // 标志是否找到待删除节点
    106         while (true) {
    107             if (temp.next == null) {
    108                 break;
    109             }
    110             if (temp.next.no == no) {
    111                 // 找到了待删除节点的前一个节点 temp
    112                 flag = true;
    113                 break;
    114             }
    115             temp = temp.next; // temp 后移
    116         }
    117         // 判断是否找到
    118         if (flag) {
    119             // 找到,可以删除
    120             temp.next = temp.next.next;
    121         } else {
    122             System.out.printf("要删除的%d节点不存在", no);
    123         }
    124     }
    125 
    126     // 显示链表【遍历】
    127     public void list() {
    128         // 判断链表是否为空
    129         if (head.next == null) {
    130             System.out.println("链表为空");
    131             return;
    132         }
    133 
    134         // 因为头节点不能动,需要辅助变量来遍历
    135         HeroNode temp = head.next;
    136         while (true) {
    137             // 判断是否到链表最后
    138             if (temp == null) {
    139                 break;
    140             }
    141             // 输出节点信息
    142             System.out.println(temp);
    143             // 将 next 后移
    144             temp = temp.next;
    145         }
    146     }
    147 
    148     // 第二种方式在添加英雄时,根据排名将英雄插入到指定位置
    149     // 如果有这个排名,则添加失败,并给出提示
    150     public void addByorder(HeroNode heroNode) {
    151         // 因为头节点不能动,因此需要通过一个辅助指针(变量)来帮助找到添加的位置
    152         // 因为单链表,因为找到的 temp 是位于添加位置的前一个节点,否则无法插入
    153         HeroNode temp = head;
    154         boolean flag = false; // 标志添加的编号是否存在,默认为false
    155         while (true) {
    156             if (temp.next == null) { // 说明 temp 以及在链表最后
    157                 break;
    158             }
    159             if (temp.next.no > heroNode.no) { // 找到位置,就在temp的后面插入
    160                 break;
    161             } else if (temp.next.no == heroNode.no) {
    162                 flag = true; // 编号存在
    163                 break;
    164             }
    165             temp = temp.next; // 后移,遍历当前链表
    166         }
    167 
    168         // 判断 flag 的值
    169         if (flag) {
    170             System.out.printf("准备插入的英雄的编号%d已经存在,不能加入\n", heroNode.no);
    171         } else {
    172             // 插入到链表中
    173             heroNode.next = temp.next;
    174             temp.next = heroNode;
    175         }
    176 
    177     }
    178 
    179 }
    180 
    181 // 定义 HeroNode,每个 HeroNode 对象就是一个节点
    182 class HeroNode {
    183     public int no;
    184     public String name;
    185     public String nickname;
    186     public HeroNode next; // 指向下一个节点
    187 
    188     // 构造器
    189     public HeroNode(int no, String name, String nickname) {
    190         this.no = no;
    191         this.name = name;
    192         this.nickname = nickname;
    193     }
    194 
    195     @Override
    196     public String toString() {
    197         return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
    198     }
    199 
    200 }

            

  • 相关阅读:
    2015上阅读计划
    《梦断代码》读书笔记 第2篇
    四则运算3
    求数组中最大子数组的和(一维)
    四则运算2—单元测试
    四则运算2
    《梦断代码》读书笔记 第1篇
    四组运算2(思路)
    四则运算1
    读书笔记
  • 原文地址:https://www.cnblogs.com/niujifei/p/11561459.html
Copyright © 2020-2023  润新知