单链表应用实例及代码实现

问题:使用带 head 头的单向链表实现 –英雄列表管理完成对英雄人物的增删改查操作。

首先准备一个hero类:

1. class hero {  
2.     private int num;//序号(排名)  
3.     private String name;//名称  
4.     private String nikname;//别名  
5.     private hero next;//指向下一个  
6.   
7.     public hero(int num, String name, String nikname) {  ... }  //构造器
8.   
9.     public int getNum() {  ... }  
10.     public void setNum(int num) {   ... }  
11.     public String getName() {  ...  }  
12.     public void setName(String name) {  ... }  
13.     public String getNikname() {   ... }  
14.     public void setNikname(String nikname) {  ...  }  
15.     public hero getNext() {   ... }  
16.     public void setNext(hero next) { ...   }  
17.     
18.     @Override  
19.     public String toString() {  ...  }  //为了显示方便显示重写tostring  
20. }  

1) 第一种方法:在添加英雄时,直接添加到链表的尾部(add())
思路分析:
  添加(创建)
    1、先创建一个head头节点(①不存放具体数据,②作用就是表示单链表头next)
     
     private hero head = new hero(-1, "", ""); //先初始化一个头节点,头节点不能动,不存放具体数据  

    2、之后我们每添加一个节点,就直接加入到链表的最后

  遍历
    1、通过一个辅助变量遍历,帮助遍历整个链表
2) 第二种方式在添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)
  思路分析:
    1、首先找到新添加的节点的位置,是通过辅助变量,通过遍历来搞定
    2、 新的节点.next=temp.next (temp为插入后的新节点的前一个节点)
    3、将temp.next=新的节点
3) 修改节点
  思路分析:
    1、 先找到该节点,通过遍历
    2、 temp.name = newHero.name ; temp.nickname= newHero.nickname; 
4) 删除节点(delete())
  思路分析:
    1、先找到需要删除的这个节点的前一个节点temp
    2、 temp.next=temp.next.next 
    3、删除的节点,将不会有其他引用,会被GC掉

 

 

单链表代码实现:

1. public class singlelinkedlist {  
2.     //先初始化一个头节点,头节点不能动,不存放具体数据  
3.     private hero head = new hero(-1, "", "");  
4.   
5.     //添加节点到单向链表  
6.     /** 
7.      * 思路:当不考虑标编号顺序时 
8.      * 1、找到当前链表的最后节点 
9.      * 2、将最后这个节点的next指向新的节点 
10.      */  
11.     public void add(hero h) {  
12.         //因为head节点不能动,因此我们需要一个辅助变量temp  
13.         hero temp = head;  
14.         //遍历链表,找到最后一个节点  
15.         while (true) {  
16.             if (temp.getNext() == null) {  
17.                 break;  
18.             }  
19.             //如果没有到最后,将temp后移  
20.             temp = temp.getNext();  
21.         }  
22.         //当退出while循环时,temp就指向了链表的最后  
23.         //将最后这个节点的next指向新的节点  
24.         temp.setNext(h);  
25.     }  
26.   
27.     //第二种方式在添加英雄时,根据排名将英雄插入到指定位置  
28.     //(如果有这个排名,则添加失败,并给出提示)  
29.     public void addByOrder(hero h) {  
30.         //因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置  
31.         //因为单链表,因为我们找的temp是位于 添加位置的前一个节点,否则插入不了  
32.         hero temp = head;  
33.         boolean flag = false;// flag 标志添加的编号是否存在,默认为 false  
34.         while (true) {  
35.             if (temp.getNext() == null) {//说明 temp 已经在链表的最后  
36.                 break;  
37.             } else if (temp.getNext().getNum() > h.getNum()) {//位置找到,就在 temp 的后面插入  
38.                 break;  
39.             } else if (temp.getNext().getNum() == h.getNum()) {//说明希望添加的 heroNode 的编号已然存在  
40.                 flag = true;  
41.                 break;  
42.             }  
43.             temp = temp.getNext();//后移,遍历当前链表  
44.         }  
45.         if (flag) { //不能添加,说明编号存在  
46.             System.out.println("添加的序号为" + h.getNum() + "的英雄序号已经存在,添加失败。");  
47.             return;  
48.         }  
49.         //插入到链表中, temp 的后面  
50.         h.setNext(temp.getNext());  
51.         temp.setNext(h);  
52.     }  
53.   
54.     //显示链表(遍历)  
55.     public void show() {  
56.         //判断链表是否为空  
57.         if (head.getNext() == null) {  
58.             System.out.println("show():链表为空。。。。");  
59.             return;  
60.         }  
61.         //因为头节点,不能动,因此我们需要一个辅助变量来遍历  
62.         hero temp = head.getNext();  
63.         while (true) {  
64.             //判断是否到链表最后  
65.             if (temp == null) {  
66.                 break;  
67.             }  
68.             //输出节点的信息  
69.             System.out.println(temp.toString());  
70.             //将 temp 后移, 一定小心  
71.             temp = temp.getNext();  
72.         }  
73.     }  
74.   
75.     //修改节点的信息, 根据 no 编号来修改,即 no 编号不能改.  
76.     //说明  
77.     //1.  根据 newHeroNode  的 no 来修改即可  
78.     public void update(hero h) {  
79.         hero temp = head.getNext();//定义一个辅助变量  
80.         boolean flag = false;//表示是否找到该节点  
81.         //判断链表是否空  
82.         if (head.getNext() == null) {  
83.             System.out.println("update():链表为空。。。。");  
84.             return;  
85.         }  
86.         //找到需要修改的节点, 根据 num值  
87.         while (true) {  
88.             if (temp == null) {  
89.                 break;//已经遍历完链表  
90.             }  
91.             if (temp.getNum() == h.getNum()) {  
92.                 flag = true;  
93.                 break;  
94.             }  
95.             temp = temp.getNext();  
96.         }  
97.         if (flag) {  
98.             temp.setName(h.getName());  
99.             temp.setNikname(h.getNikname());  
100.         } else {//没有找到  
101.             System.out.printf("没有找到 编号 %d  的节点,不能修改\n", h.getNum());  
102.         }  
103.     }  
104.   
105.     //删除节点  
106.     //思路  
107.     //1. head  不能动,因此我们需要一个 temp 辅助节点找到待删除节点的前一个节点  
108.     //2. 说明我们在比较时,是 temp.next.no 和需要删除的节点的 no 比较  
109.     public void delete(int n) {  
110.         hero temp = this.head;  
111.         boolean flag = false;// 标志是否找到待删除节点的  
112.         if (head.getNext() == null) {  
113.             System.out.println("delete():链表为空。。。。");  
114.             return;  
115.         }  
116.         while (true) {  
117.             if (temp.getNext() == null) {//已经到链表的最后  
118.                 break;  
119.             }  
120.             if (temp.getNext().getNum() == n) {//找到的待删除节点的前一个节点 temp  
121.                 flag = true;  
122.                 break;  
123.             }  
124.             temp = temp.getNext();//temp 后移,遍历  
125.         }  
126.         if (flag) {  
127.             temp.setNext(temp.getNext().getNext());  
128.         } else {  
129.             System.out.printf("没有找到 编号 %d  的节点,不能删除\n", n);  
130.         }  
131.   
132.     }  
133.   
134. }  

 

posted @ 2020-10-15 20:56  白刃天使  阅读(392)  评论(0编辑  收藏  举报