码迷,mamicode.com
首页 > 其他好文 > 详细

4、单链表

时间:2020-06-14 12:46:04      阅读:34      评论:0      收藏:0      [点我收藏+]

标签:nbsp   void   link   single   ref   tps   static   https   ide   

来源:https://www.bilibili.com/video/BV1B4411H76f?p=15

一、链表

1、以结点的方式进行存储;

2、每个结点包含data域和next域,data域存放数据,next域指向下一个结点;

3、链表各结点的存放不一定连续;

4、链表分有头结点的和没有头结点的,可以根据实际情况确定使用哪一种。

 

二、单链表创建思路

2.1 增加结点

2.1.1 直接添加到尾部

1、创建一个头结点(head),用来表示单链表的起始位置(不存放数据);

2、每当需要向尾部添加一个结点,找到下一个结点为空的【当前结点】,插入到当前结点的下一个位置;

3、从头结点开始,利用一个辅助变量(结点),通过遍历的方式寻找【当前结点】

2.1.2 按照编号或者说结点位置添加

 1、找到要添加位置的前一个结点,赋值给辅助变量(temp)

 2、【新结点.next】=【temp.next】

 3、【temp.next】=【新结点】

2.2 修改结点

 1、找到要修改的结点

 2、要修改的结点的内容变成新的内容

2.3 删除结点

 1、找到要删除结点的前一个结点,赋值给辅助变量(temp)

 2、【temp.next】=【temp.next.next】

 3、被删除的结点会被自动回收

 

三、实现

3.1 增加结点

3.1.1 直接添加到尾部

首先创建一个代表结点的类,类中的属性包括编号,名字,昵称。同时添加了构造器,重写了toString方法。

 1 //结点类
 2 public class Node {
 3     public int no;//编号
 4     public String name;//名字
 5     public String nickName;//昵称
 6     public Node next;
 7 
 8     public Node(int no, String name, String nickName) {
 9         this.no = no;
10         this.name = name;
11         this.nickName = nickName;
12     }
13 
14     @Override
15     public String toString() {
16         return "Node{" +
17                 "no=" + no +
18                 ", name=‘" + name + ‘\‘‘ +
19                 ", nickName=‘" + nickName + ‘\‘‘ +
20                 ‘}‘;
21     }
22 }

之后创建了代表单链表的类,通过调用结点,实现单链表。类中包含一个私有的头结点属性,头结点确定后不再改变,遍历时创建一个辅助变量进行循环。目前在类中实现了一个添加结点的方法(向尾部添加),同时为了便于测试,额外增加了一个展示当前链表的方法,从头结点开始依次遍历,展示当前链表的所有结点。

 1 //单链表,管理创建出来的结点
 2 public class SingleLinkedList {
 3     //初始化头结点
 4     private Node head = new Node(0,"","");
 5 
 6     //向单链表尾部添加新结点
 7     public void addNode(Node newNode){
 8         Node temp = head;//通过辅助变量temp遍历单链表,找到尾部的位置
 9         while (true){
10             if(temp.next == null){
11                 break;
12             }
13             temp = temp.next;
14         }
15         temp.next = newNode;
16     }
17 
18     //展示链表内容
19     public void show(){
20         if(head.next == null){
21             System.out.println("链表为空,无法展示");
22             return;
23         }
24         Node temp = head.next;
25         while (true){
26             if(temp == null){
27                 break;
28             }
29             System.out.println(temp);
30             temp = temp.next;
31         }
32     }
33 }

测试

 1     public static void main(String[] args) {
 2         Scanner sc = new Scanner(System.in);
 3 
 4         SingleLinkedList singleLinkedList = new SingleLinkedList();
 5 
 6         Node node1 = new Node(1, "张三", "Tom");
 7         Node node2 = new Node(2, "李四", "Jerry");
 8         Node node3 = new Node(3, "王五", "Simba");
 9         Node node4 = new Node(4, "赵六", "Shrek");
10 
11         singleLinkedList.show();
12         System.out.println();
13 
14         singleLinkedList.addNode(node1);
15         singleLinkedList.show();
16         System.out.println();
17 
18         singleLinkedList.addNode(node2);
19         singleLinkedList.show();
20         System.out.println();
21 
22         singleLinkedList.addNode(node3);
23         singleLinkedList.show();
24         System.out.println();
25 
26         singleLinkedList.addNode(node4);
27         singleLinkedList.show();
28 
29 
30     }

结果

链表为空,无法展示

Node{no=1, name=‘张三‘, nickName=‘Tom‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}
Node{no=4, name=‘赵六‘, nickName=‘Shrek‘}

3.1.2 按照编号或者说结点位置添加

SingleLinkedList类中加入按照编号添加节点的方法(这里是按照结点中的编号属性从小到大排列结点)

 1     public void addByOrder(Node newNode){
 2         Node temp = head;
 3         //考虑到可能存在相同的结点编号,这里用一个flag表示是否已经存在相同的编号
 4         boolean flag = false;//默认链表中不存在newNode所属的编号
 5         while (true){
 6             //当前结点下一个为空
 7             if(temp.next == null){
 8                 break;
 9             }
10             //当前结点下一个结点编号大于新结点的编号,应该将新结点插入到当前节点后面(按编号从小到大排列)
11             if(temp.next.no > newNode.no){
12                 break;
13             }
14             //当前结点下一个结点编号与新结点相同,已经存在了,不再添加
15             if(temp.next.no == newNode.no){
16                 flag = true;
17                 break;
18             }
19             temp = temp.next;
20         }
21         if(flag){
22             System.out.printf("编号%d存在了",newNode.no);
23             System.out.println();
24         }else {
25             newNode.next = temp.next;
26             temp.next = newNode;
27         }
28     }

测试

 1     public static void main(String[] args) {
 2 
 3         SingleLinkedList singleLinkedList = new SingleLinkedList();
 4 
 5         Node node1 = new Node(1, "张三", "Tom");
 6         Node node2 = new Node(2, "李四", "Jerry");
 7         Node node3 = new Node(3, "王五", "Simba");
 8         Node node4 = new Node(4, "赵六", "Shrek");
 9 
10         singleLinkedList.show();
11         System.out.println();
12 
13         singleLinkedList.addByOrder(node4);
14         singleLinkedList.show();
15         System.out.println();
16 
17         singleLinkedList.addByOrder(node1);
18         singleLinkedList.show();
19         System.out.println();
20 
21         singleLinkedList.addByOrder(node3);
22         singleLinkedList.show();
23         System.out.println();
24 
25         singleLinkedList.addByOrder(node4);
26         singleLinkedList.show();
27         System.out.println();
28 
29         singleLinkedList.addByOrder(node2);
30         singleLinkedList.show();
31         System.out.println();
32     }

结果

链表为空,无法展示

Node{no=4, name=‘赵六‘, nickName=‘Shrek‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=4, name=‘赵六‘, nickName=‘Shrek‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}
Node{no=4, name=‘赵六‘, nickName=‘Shrek‘}

编号4存在了
Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}
Node{no=4, name=‘赵六‘, nickName=‘Shrek‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}
Node{no=4, name=‘赵六‘, nickName=‘Shrek‘}

3.2 修改结点

在SingleLinkedList类中加入修改结点的方法

 1     //修改节点
 2     public void update(Node newNode){
 3         if(head.next == null){
 4             System.out.println("链表为空,无法修改");
 5             return;
 6         }
 7         Node temp = head.next;
 8         //是否找到要修改的结点
 9         boolean flag = false;
10 
11         while (true){
12             if(temp == null){//没有与新结点编号一致的可以修改的结点
13                 break;
14             }
15             if(temp.no == newNode.no){
16                 flag = true;
17                 break;
18             }
19             temp = temp.next;
20         }
21         if(flag){
22             temp.name = newNode.name;
23             temp.nickName = newNode.nickName;
24         }else {
25             System.out.printf("没有找到编号为%d的结点",newNode.no);
26             System.out.println();
27         }
28     }

测试

 1     public static void main(String[] args) {
 2 
 3         SingleLinkedList singleLinkedList = new SingleLinkedList();
 4 
 5         Node node1 = new Node(1, "张三", "Tom");
 6         Node node2 = new Node(2, "李四", "Jerry");
 7         Node node3 = new Node(3, "王五", "Simba");
 8         Node node4 = new Node(1, "赵六", "Shrek");
 9         Node node5 = new Node(5, "田七", "Shrek");
10 
11         singleLinkedList.show();
12         System.out.println();
13 
14         singleLinkedList.addByOrder(node1);
15         singleLinkedList.addByOrder(node2);
16         singleLinkedList.addByOrder(node3);
17         singleLinkedList.show();
18         System.out.println();
19 
20         singleLinkedList.update(node5);
21         singleLinkedList.show();
22         System.out.println();
23 
24         singleLinkedList.update(node4);
25         singleLinkedList.show();
26         System.out.println();
27 
28     }

结果

链表为空,无法展示

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}

没有找到编号为5的结点
Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}

Node{no=1, name=‘赵六‘, nickName=‘Shrek‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}

3.3 删除结点

在SingleLinkedList类中加入删除结点的方法

 1     public void delete(int no){
 2         if(head.next == null){
 3             System.out.println("链表为空,无法删除");
 4             return;
 5         }
 6         Node temp = head;
 7         //是否找到要删除的结点的前一个结点
 8         boolean flag = false;
 9 
10         while (true){
11             if(temp.next == null){
12                 break;
13             }
14             if(temp.next.no == no){
15                 flag = true;
16                 break;
17             }
18             temp = temp.next;
19         }
20 
21         if(flag){
22             temp.next = temp.next.next;
23         }else {
24             System.out.printf("没有找到编号为%d的结点",no);
25             System.out.println();
26         }
27     }

测试

 1     public static void main(String[] args) {
 2 
 3         SingleLinkedList singleLinkedList = new SingleLinkedList();
 4 
 5         Node node1 = new Node(1, "张三", "Tom");
 6         Node node2 = new Node(2, "李四", "Jerry");
 7         Node node3 = new Node(3, "王五", "Simba");
 8 
 9         singleLinkedList.show();
10         System.out.println();
11 
12         singleLinkedList.addByOrder(node1);
13         singleLinkedList.addByOrder(node2);
14         singleLinkedList.addByOrder(node3);
15         singleLinkedList.show();
16         System.out.println();
17 
18         singleLinkedList.delete(2);
19         singleLinkedList.show();
20         System.out.println();
21 
22         singleLinkedList.delete(3);
23         singleLinkedList.show();
24         System.out.println();
25 
26         singleLinkedList.delete(2);
27         singleLinkedList.show();
28         System.out.println();
29 
30         singleLinkedList.delete(1);
31         singleLinkedList.show();
32         System.out.println();
33 
34     }

结果

链表为空,无法展示

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=2, name=‘李四‘, nickName=‘Jerry‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}
Node{no=3, name=‘王五‘, nickName=‘Simba‘}

Node{no=1, name=‘张三‘, nickName=‘Tom‘}

没有找到编号为2的结点
Node{no=1, name=‘张三‘, nickName=‘Tom‘}

链表为空,无法展示

 

4、单链表

标签:nbsp   void   link   single   ref   tps   static   https   ide   

原文地址:https://www.cnblogs.com/zhao-xin/p/13110244.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!