首页 > 技术文章 > 5、链表-双向链表

zhao-xin 2020-06-16 11:02 原文

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

一、介绍

相比单链表来说

1、双向链表可以向前和向后查找,而单链表只能查找一个方向;

2、双向链表可以自我删除,单链表只能通过辅助结点,即需要找到要删除的结点前面的那个结点。

 

二、双向链表思路

2.1、增加结点

1、添加到链表尾部

新建一个结点类,结点类中除了单链表中已经有的属性,还要添加一个属性(pre)指向前一个结点。

找到最后一个结点,需要注意的是,前后都要兼顾

2、按照位置添加

依然需要找到要添加位置的前一个结点temp

后面

  【newNode.next = temp.next】

  【temp.next.pre = newNode】

前面

  【temp.next = newNode】

  【newNode.pre = temp】

2.2、修改结点

与单链表相似

2.3、删除结点

找到要删除的结点temp

【temp.pre.next】=【temp.next】

【temp.next.pre】=【temp.pre】

三、实现

 结点

 1 public class Node2 {
 2     public int no;//编号
 3     public String name;//名字
 4     public String nickName;//昵称
 5     public Node2 next;
 6     public Node2 pre;
 7 
 8     public Node2(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 "Node2{" +
17                 "no=" + no +
18                 ", name='" + name + '\'' +
19                 ", nickName='" + nickName + '\'' +
20                 '}';
21     }
22 }

双向链表

  1 public class DoubleLinkedList {
  2     private Node2 head = new Node2(0,"","");
  3 
  4     //向链表尾部添加新结点
  5     public void addNode(Node2 newNode){
  6         Node2 temp = head;
  7         while (true){
  8             if(temp.next == null){
  9                 break;
 10             }
 11             temp = temp.next;
 12         }
 13         temp.next = newNode;
 14         newNode.pre = temp;
 15     }
 16 
 17     //按照位置添加新结点(当前按照编号no从小到大)
 18     public void addByOrder(Node2 newNode){
 19         Node2 temp = head;
 20         //避免出现相同的no
 21         boolean flag = false;
 22         while (true){
 23             if(temp.next == null){
 24                 break;
 25             }
 26             if(temp.next.no > newNode.no){
 27                 break;
 28             }
 29             if(temp.next.no == newNode.no){
 30                 flag = true;
 31                 break;
 32             }
 33             temp = temp.next;
 34         }
 35         if(flag){
 36             System.out.printf("编号%d已经存在",newNode.no);
 37             System.out.println();
 38         }else {
 39             if(temp.next != null){
 40                 newNode.next = temp.next;
 41                 temp.next.pre = newNode;
 42             }
 43             temp.next = newNode;
 44             newNode.pre = temp;
 45         }
 46     }
 47 
 48     //修改结点
 49     public void update(Node2 newNode){
 50         if(head.next == null){
 51             System.out.println("链表为空,无法修改");
 52             return;
 53         }
 54         Node2 temp = head.next;
 55         boolean flag = false;//默认找不到对应的结点
 56         while(true){
 57             if(temp == null){
 58                 break;
 59             }
 60             if(temp.no == newNode.no){
 61                 flag = true;
 62                 break;
 63             }
 64             temp = temp.next;
 65         }
 66         if(flag){
 67             temp.name = newNode.name;
 68             temp.nickName = newNode.nickName;
 69         }else {
 70             System.out.printf("没有找到编号为%d的结点",newNode.no);
 71             System.out.println();
 72         }
 73     }
 74 
 75     //删除结点
 76     public void delete(int no){
 77         if(head.next == null){
 78             System.out.println("链表为空,无法删除");
 79             return;
 80         }
 81         boolean flag = false;//默认找不到这个结点
 82         Node2 temp = head.next;
 83         while (true){
 84             if(temp == null){
 85                 break;
 86             }
 87             if(temp.no == no){
 88                 flag = true;
 89                 break;
 90             }
 91             temp = temp.next;
 92         }
 93 
 94         if(flag){
 95             temp.next.pre = temp.pre;
 96             temp.pre.next = temp.next;
 97         }else {
 98             System.out.printf("没有找到编号为%d的结点",no);
 99             System.out.println();
100         }
101     }
102 
103     public void show(){
104         if(head.next == null){
105             System.out.println("链表为空,无法展示");
106             return;
107         }
108         Node2 temp = head.next;
109         while (temp != null){
110             System.out.println(temp);
111             temp = temp.next;
112         }
113     }
114 }

它的测试与单链表相似,这里就不再添加测试代码了。

推荐阅读