关于双向链表的介绍以及代码实现
1 双向链表
1.1 介绍
- 单向链表的对比:
- 单向链表查找的方向只能是一个方向,而双向链表可以向前或向后查找
- 单向链表不能自我删除,需要靠辅助接点,而双向链表则可以自我删除
1.2 思路
- (1)新增节点
- (2)删除节点
1.3 代码实现
- 双向链表的创建和单向链表的基本一致,只是部分对数据的修改方法要多写几步有所不同
- (1)代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176public class DoubleLinkedList {
//双向链表节点类
private class DoubleNode {
public DoubleNode pre; //前一个节点
public Object data; //数据
public DoubleNode next; //后一个节点
public DoubleNode(Object data) {
this.data = data;
}
public String toString() {
return "DoubleNode{ data = " + data + " }";
}
}
private DoubleNode headNode; //头结点
public DoubleLinkedList() {
this.headNode = new DoubleNode(null);
}
/**
* 添加数据(尾插)
* @param data 数据
*/
public void add(Object data) {
DoubleNode temp = headNode;
while(temp.next != null) {
temp = temp.next;
}
//尾插
DoubleNode newNode = new DoubleNode(data);
temp.next = newNode;
newNode.pre = temp;
}
/**
* 插入数据(节点间插)
* @param data 数据
* @param index 下标
*/
public void addByIndex(Object data, int index) {
DoubleNode temp = headNode.next;
//检验数据合法性
if (index < 0 || index > getSize()) {
System.out.println("error:Index越界,请重新去确认index大小!");
return;
}
//index等于链表长度,直接尾插
if(index == getSize()) {
add(data);
return;
}
int count = 0;
while (count != index) {
temp = temp.next;
count ++;
}
//节点间插
DoubleNode newNode = new DoubleNode(data);
temp.pre.next = newNode;
newNode.pre = temp.pre;
newNode.next = temp;
temp.pre = newNode;
}
/**
* 修改数据
* @param data 数据
* @param index 下标
*/
public void updateByIndex(Object data, int index) {
DoubleNode temp = headNode.next;
if(temp == null) {
System.out.println("链表为空!");
return;
}
//数据合法性校验
if(index < 0 || index > getSize()-1) {
System.out.println("error:Index数据不合法,请重新确认index的大小!");
return;
}
int count = 0;
while (count != index) {
count ++;
temp = temp.next;
}
//修改数据
temp.data = data;
}
/**
* 删除数据
* @param index 下标
*/
public void deleteByIndex(int index) {
DoubleNode temp = headNode.next;
//空链表判断
if(temp == null) {
System.out.println("error:链表为空!");
return;
}
//数据合法校验
if(index < 0 || index > getSize()-1) {
System.out.println("error:index数据不合法,请重新确认Index的大小!");
return;
}
int count = 0;
while(count != index) {
count ++;
temp = temp.next;
}
//删除数据(注意删除最后一个数据引发空指针)
temp.pre.next = temp.next;
if(temp.next != null) {
temp.next.pre = temp.pre;
}
}
/**
* 打印双向链表
*/
public void print() {
DoubleNode temp = headNode.next;
if(temp == null) {
System.out.println("链表为空!");
return;
}
System.out.println("双向链表为:");
int count = 0;
while(temp != null) {
System.out.print(count + " - ");
System.out.println(temp);
temp = temp.next;
count ++;
}
}
/**
* 获取双向链表大小
* @return int
*/
public int getSize() {
DoubleNode temp = headNode.next;
if(temp.next == null) {
return 0;
}
int count = 0;
while(temp != null) {
count ++;
temp = temp.next;
}
return count;
}
}
- (2)测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void doubleLinkedListTest() {
//1.创建双向链表并插入数据
DoubleLinkedList linkedList = new DoubleLinkedList();
linkedList.add("hello");
linkedList.add("world");
linkedList.print();
//2. 节点间插入数据
linkedList.addByIndex("-", 1);
linkedList.print();
//3. 修改数据
linkedList.updateByIndex("!~!", 1);
linkedList.print();
//4. 删除数据
linkedList.deleteByIndex(1);
linkedList.print();
}