6.3 双向链表
单项链表的缺点分析:
-
单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后
-
单向链表不能进行自我删除,需要靠辅助节点,而双向链表,则可以自我删除,所以前面我们单向链表删除时,总是找到
temp
,temp
是待删除节点的前一个节点
双向链表与单向链表相似,但是多了一个指向前一个节点的指针
分析:
-
遍历方法和单链表相似,只是可以向前,也可以向后查找
-
添加(默认添加到双向链表的最后)
-
先找到双向链表的最后这个节点
-
temp.next = newNode
-
newNode.pre = temp
-
-
修改 思路和原来的单向链表一样
-
删除
-
-
直接找到要删除的这个节点,比如
temp
-
temp.pre.next = temp.next
-
temp.next.pre = temp.pre
-
1 package LinckedList; 2 3 public class DoubleLinkedListDemo { 4 public static void main(String[] args) { 5 DoubleLinkedList s2 = new DoubleLinkedList(); 6 DoubleNode d1 = new DoubleNode(1,"a"); 7 DoubleNode d2 = new DoubleNode(2,"b"); 8 DoubleNode d3 = new DoubleNode(3,"c"); 9 10 s2.addNode(d1); 11 s2.addNode(d3); 12 s2.addNode(d2); 13 14 s2.list(); 15 16 System.out.println("修改"); 17 DoubleNode d4 = new DoubleNode(3,"d"); 18 s2.upadate(d4); 19 s2.list(); 20 21 System.out.println("删除"); 22 s2.del(2); 23 s2.list(); 24 25 } 26 } 27 class DoubleLinkedList{ 28 private DoubleNode head = new DoubleNode(0,""); 29 30 // 获取头节点 31 public DoubleNode getHead(){ 32 return head; 33 } 34 35 // 遍历双向链表 36 public void list(){ 37 if (head.next == null){ 38 System.out.println("链表为空"); 39 return; 40 } 41 DoubleNode temp = head.next; 42 while (true){ 43 if (temp == null){ 44 break; 45 } 46 System.out.println(temp); 47 temp = temp.next; 48 } 49 } 50 51 // 添加数据 52 public void addNode(DoubleNode node){ 53 DoubleNode temp = head; 54 boolean flag = false; 55 while (true){ 56 if (temp.next == null){ 57 break; 58 } 59 if (temp.next.id == node.id){ 60 flag = true; 61 break; 62 }else if(temp.next.id > node.id){ 63 break; 64 } 65 temp = temp.next; 66 } 67 if (flag){ 68 System.out.println("Has exsist"); 69 return; 70 }else { 71 node.next = temp.next; 72 temp.next = node; 73 node.pre = temp; 74 } 75 76 } 77 78 // 修改 双向链表的修改和单向链表一样,只是节点类型改成DoubleNode 79 public void upadate(DoubleNode node){ 80 DoubleNode temp = head.next; 81 boolean flag = false; // 判断是否找到当前值 82 while (true){ 83 if (temp == null){ 84 break; 85 } 86 if (temp.id == node.id){ 87 flag = true; 88 break; 89 } 90 temp = temp.next; 91 } 92 if (flag){ 93 temp.id = node.id; 94 temp.name = node.name; 95 }else { 96 System.out.println("不存在"); 97 } 98 } 99 100 // 删除节点 101 // 说明 102 // 1. 对于双向链表,我们可以直接找到要删除的点 103 // 2. 找到后自我删除就好 104 public void del(int id){ 105 if (head.next == null){ 106 System.out.println("NULL List"); 107 return; 108 } 109 DoubleNode temp = head.next; 110 boolean flag = false; 111 while (true){ 112 if (temp == null){ 113 break; 114 } 115 if (temp.id == id){ 116 flag = true; 117 break; 118 } 119 temp = temp.next; 120 } 121 // 判断flag 122 if (flag){ 123 temp.pre.next = temp.next; 124 // 如果是最后这个节点就不需要执行下面这段话 125 if (temp.next != null){ 126 temp.next.pre = temp.pre; 127 } 128 }else { 129 System.out.println("不存在"); 130 } 131 } 132 } 133 class DoubleNode{ 134 public int id; 135 public String name; 136 public DoubleNode pre; 137 public DoubleNode next; 138 139 public DoubleNode(int id, String name) { 140 this.id = id; 141 this.name = name; 142 } 143 144 @Override 145 public String toString() { 146 return "DoubleNode{" + 147 "id=" + id + 148 ", name='" + name + '\'' + 149 '}'; 150 } 151 } 152
package LinckedList;
public class DoubleLinkedListDemo {
public static void main(String[] args) {
DoubleLinkedList s2 = new DoubleLinkedList();
DoubleNode d1 = new DoubleNode(1,"a");
DoubleNode d2 = new DoubleNode(2,"b");
DoubleNode d3 = new DoubleNode(3,"c");
s2.addNode(d1);
s2.addNode(d3);
s2.addNode(d2);
s2.list();
System.out.println("修改");
DoubleNode d4 = new DoubleNode(3,"d");
s2.upadate(d4);
s2.list();
System.out.println("删除");
s2.del(2);
s2.list();
}
}
class DoubleLinkedList{
private DoubleNode head = new DoubleNode(0,"");
// 获取头节点
public DoubleNode getHead(){
return head;
}
// 遍历双向链表
public void list(){
if (head.next == null){
System.out.println("链表为空");
return;
}
DoubleNode temp = head.next;
while (true){
if (temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
// 添加数据
public void addNode(DoubleNode node){
DoubleNode temp = head;
boolean flag = false;
while (true){
if (temp.next == null){
break;
}
if (temp.next.id == node.id){
flag = true;
break;
}else if(temp.next.id > node.id){
break;
}
temp = temp.next;
}
if (flag){
System.out.println("Has exsist");
return;
}else {
node.next = temp.next;
temp.next = node;
node.pre = temp;
}
}
// 修改 双向链表的修改和单向链表一样,只是节点类型改成DoubleNode
public void upadate(DoubleNode node){
DoubleNode temp = head.next;
boolean flag = false; // 判断是否找到当前值
while (true){
if (temp == null){
break;
}
if (temp.id == node.id){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.id = node.id;
temp.name = node.name;
}else {
System.out.println("不存在");
}
}
// 删除节点
// 说明
// 1. 对于双向链表,我们可以直接找到要删除的点
// 2. 找到后自我删除就好