java与数据结构(4)---java实现双向循环链表
分类:
IT文章
•
2022-07-28 21:49:06
线性表之链式存储结构双向循环链表
双向循环链表:每个结点包含了数据、直接前驱地址指针和直接后驱地址指针,头结点的直接前驱指向尾结点,尾结点的直接后驱指向头结点,头尾相连构成一个可正可反的圆环。可以形象的理解成一群孩子手拉手牵成一个圆圈,从头一个孩子开始可以从左往右报数,也可以从右往左开始报数。
优点:双向循环链表可以迅速的获取当前数据的前驱数据,解决了单向循环链表从头开始遍历的麻烦。
接口类
1 package list;
2
3 public interface Listable<T> {
4
5 public void clear();
6
7 public boolean isEmpty();
8
9 public int Length();
10
11 public T getElement(int index);
12
13 public boolean add(T element);
14
15 public boolean addHead(T element);
16
17 public boolean addByIndex(int index, T element);
18
19 public boolean add(Listable<T> list);
20
21 public T remove(int index);
22
23 public boolean removeAll();
24
25 public T remove(T element);
26
27 public T setElement(int index,T element);
28
29 }
View Code
结点类
1 //结点类
2 class Node<T> {
3 private Node<T> left,right;
4 private T data;
5
6 Node(T data) {
7 this(data,null,null);
8 }
9
10 Node() {
11 this(null,null,null);
12 }
13
14 Node(T data,Node<T> left,Node<T> right) {
15 this.data = data;
16 this.left = left;
17 this.right = right;
18 }
19
20 public T getData() {
21 return this.data;
22 }
23
24 public Node<T> getLeft() {
25 return this.left;
26 }
27
28 public Node<T> getRight() {
29 return this.right;
30 }
31
32 public void setData(T data) {
33 this.data = data;
34 }
35
36 public void setRight(Node<T> right) {
37 this.right = right;
38 }
39
40 public void setLeft(Node<T> left) {
41 this.left = left;
42 }
43
44 public String toString() {
45 return getData().toString();
46 }
47 }
View Code
接口实现类
1 //接口实现类
2 class DoubleLinkedList<T> implements Listable<T> {
3 public Node<T> head;
4
5 //建空表,带头结点
6 DoubleLinkedList() {
7 this(null);
8 }
9
10 //建表,带头结点,表中有一条数据元素
11 DoubleLinkedList(T element) {
12 if(element == null) {
13 head = new Node<T>(element,null,null);
14 head.setRight(head);
15 head.setLeft(head);
16 }else {
17 Node<T> headRight = new Node<T>(element,null,null);
18 head = new Node<T>(null,headRight,headRight);
19 headRight.setLeft(head);
20 headRight.setRight(head);
21 }
22 }
23
24 //清空当前链表
25 public void clear() {}
26
27 //判空表
28 public boolean isEmpty() {
29 return head.getRight() == head;
30 }
31
32 //表长
33 public int Length() {
34 int len = 0;
35 Node<T> temp = head;
36 while(temp.getRight() != head) {
37 len++;
38 temp = temp.getRight();
39 }
40 return len;
41 }
42
43 //取下标index处的数据
44 public T getElement(int index) {
45 if(index <= 0) {
46 return head.getRight().getData();
47 }
48 int len = Length();
49 if(index >= len) {
50 return head.getLeft().getData();
51 }
52 T element = null;
53 if(index > 0 && index < len) {
54 int k = 0;
55 Node<T> temp = head;
56 //此处只能用while不能用if,用错好几次
57 while(k <= index && temp.getRight() != head) {
58 k++;
59 temp = temp.getRight();
60 }
61 element = temp.getData();
62 }
63 return element;
64 }
65
66 //尾添
67 public boolean add(T element) {
68 if(element == null) return false;
69 Node<T> node = new Node<T>(element,head.getLeft(),head);
70 head.getLeft().setRight(node);
71 head.setLeft(node);
72 return true;
73 }
74
75 //首添
76 public boolean addHead(T element) {
77 if(element == null) return false;
78 Node<T> node = new Node<T>(element,head,head.getRight());
79 head.getRight().setLeft(node);
80 head.setRight(node);
81 return false;
82 }
83
84 //表index处,添加新数据element
85 public boolean addByIndex(int index, T element) {
86 if(index <= 0) {
87 return addHead(element);
88 }else if(index >= Length()) {
89 return add(element);
90 }else {
91 int k = 0;
92 Node<T> temp = head;
93 //此处只能用while不能用if,用错好几次
94 while(k <= index && temp.getRight() != head) {
95 k++;
96 temp = temp.getRight();
97 }
98 Node<T> node = new Node<T>(element,temp.getLeft(),temp);
99 temp.getLeft().setRight(node);
100 temp.setLeft(node);
101 }
102 return true;
103 }
104
105 //将参数中的链表添加到当前链表的尾部
106 public boolean add(Listable<T> slist) {
107 if(slist.isEmpty() || slist == null) return false;
108 if(slist instanceof DoubleLinkedList) {
109 DoubleLinkedList<T> list = (DoubleLinkedList<T>)slist;
110 //以下操作影响到了添加的slist表,所以需要将slist表重新备份一个
111 DoubleLinkedList<T> temp = new DoubleLinkedList<T>();
112 for(int i = 0; i < list.Length(); i++) {
113 temp.add(list.getElement(i));
114 }
115 Node<T> node = temp.head;
116 Node<T> nodeLeft = node.getLeft();
117 Node<T> nodeRight = node.getRight();
118 this.head.getLeft().setRight(node.getRight());
119 nodeRight.setLeft(this.head.getLeft());
120 nodeLeft.setRight(this.head);
121 this.head.setLeft(node.getLeft());
122 return true;
123 }else {
124 return false;
125 }
126 }
127
128 //删除下标Index处的数据
129 public T remove(int index) {
130 if(isEmpty()) return null;
131 if(index < 0) {
132 index = 0;
133 }
134 int len = Length();
135 if(index >= len) {
136 //当index大于或等于表长是,默认移走表的最后一个元素,即下标为len-1的数据
137 index = len-1;
138 }
139 T element = null;
140 if(index >= 0 && index < len) {
141 Node<T> temp = head;
142 int k = 0;
143 while(k <= index && temp.getRight() != head) {
144 k++;
145 temp = temp.getRight();
146 }
147 element = temp.getData();
148 temp.getRight().setLeft(temp.getLeft());
149 temp.getLeft().setRight(temp.getRight());
150 temp.setRight(null);
151 temp.setLeft(null);
152 temp = null;
153 }
154 return element;
155 }
156
157 //删除当前链表中所有的数据,只剩头结点
158 public boolean removeAll() {
159 if(isEmpty()) return false;
160 Node<T> temp = head.getRight();
161 while(temp != head) {
162 head.setRight(temp.getRight());
163 temp.getRight().setLeft(head);
164 temp.setLeft(null);
165 temp.setRight(null);
166 temp = head.getRight();
167 }
168 return true;
169 }
170
171 //删除链表中从head开始的第一个element数据
172 public T remove(T element) {
173 if(isEmpty() || element == null) return null;
174 //从表中第一个元素开始比较
175 Node<T> temp = head.getRight();
176 int k=0;
177 while(temp != head) {
178 if(element.equals(temp.getData())) {
179 remove(k);
180 return element;
181 }else {
182 temp = temp.getRight();
183 k++;
184 }
185 }
186 if(k == (Length()-1)) {
187 System.out.println("该链表中没有该数据");
188 }
189 return element;
190 }
191
192 //修改下标index处的数据,并将原始数据返回
193 public T setElement(int index,T element) {
194 if(index < 0 || index >= Length()) return null;
195 Node<T> temp = head;
196 int k = 0;
197 while(k < index && temp.getRight() != head) {
198 k++;
199 temp = temp.getRight();
200 }
201 T tempEle = temp.getData();
202 temp.setData(element);
203 return tempEle;
204 }
205
206 //重写父类toString方法,实际是给list做遍历后将数据打印出来
207 public String toString() {
208 StringBuffer sb = new StringBuffer();
209 /*通过for循环遍历双向循环链表
210 int length = Length();
211 sb.append("[ ");
212 for(int i = 0; i < length; i++) {
213 sb.append(getElement(i)+" ");
214 }
215 sb.append("]");
216 */
217 //从表头开始遍历双向循环链表
218 sb.append("[ ");
219 Node<T> node = head;
220 while(node.getRight() != head) {
221 sb.append(node.getRight().getData()+" ");
222 node = node.getRight();
223 }
224 sb.append("]");
225 return sb.toString();
226 }
227
228 }
View Code
测试类
1 package list;
2
3 //************************************************
4 //*双向循环链表-java实现(画图分析会容易理解得多)
5 //************************************************
6
7 public class TestDoubleLinkedList {
8 public static void main(String[] args) {
9 Listable<String> list = new DoubleLinkedList<String>("a");
10 list.add("b");
11 list.add("c");
12 list.addByIndex(3,"e");
13 list.addByIndex(3,"d");
14 list.addByIndex(5,"f");
15 System.out.println(list);
16 list.addHead("A");
17 System.out.println(list.Length());
18 System.out.println(list);
19 Listable<String> list1 = new DoubleLinkedList<String>("123456");
20 list.add(list1);
21 System.out.println(list);
22 list.remove(100);
23 list.add("123456");
24 System.out.println("list="+list);
25 System.out.println(list1);
26 list1.removeAll();
27 System.out.println(list1+" list1 is Empty??"+list1.isEmpty());
28 list.remove("123456");
29 System.out.println("list="+list);
30 System.out.println("remove item="+list.remove("A"));
31 System.out.println("list="+list);
32 }
33 }
View Code
1 package list;
2
3 //************************************************
4 //*双向循环链表-java实现(画图分析会容易理解得多)
5 //************************************************
6
7 public class TestDoubleLinkedList {
8 public static void main(String[] args) {
9 Listable<String> list = new DoubleLinkedList<String>("a");
10 list.add("b");
11 list.add("c");
12 list.addByIndex(3,"e");
13 list.addByIndex(3,"d");
14 list.addByIndex(5,"f");
15 System.out.println(list);
16 list.addHead("A");
17 System.out.println(list.Length());
18 System.out.println(list);
19 Listable<String> list1 = new DoubleLinkedList<String>("123456");
20 list.add(list1);
21 System.out.println(list);
22 list.remove(100);
23 list.add("123456");
24 System.out.println("list="+list);
25 System.out.println(list1);
26 list1.removeAll();
27 System.out.println(list1+" list1 is Empty??"+list1.isEmpty());
28 list.remove("123456");
29 System.out.println("list="+list);
30 System.out.println("remove item="+list.remove("A"));
31 System.out.println("list="+list);
32 }
33 }
34
35 //结点类
36 class Node<T> {
37 private Node<T> left,right;
38 private T data;
39
40 Node(T data) {
41 this(data,null,null);
42 }
43
44 Node() {
45 this(null,null,null);
46 }
47
48 Node(T data,Node<T> left,Node<T> right) {
49 this.data = data;
50 this.left = left;
51 this.right = right;
52 }
53
54 public T getData() {
55 return this.data;
56 }
57
58 public Node<T> getLeft() {
59 return this.left;
60 }
61
62 public Node<T> getRight() {
63 return this.right;
64 }
65
66 public void setData(T data) {
67 this.data = data;
68 }
69
70 public void setRight(Node<T> right) {
71 this.right = right;
72 }
73
74 public void setLeft(Node<T> left) {
75 this.left = left;
76 }
77
78 public String toString() {
79 return getData().toString();
80 }
81 }
82
83 //接口实现类
84 class DoubleLinkedList<T> implements Listable<T> {
85 public Node<T> head;
86
87 //建空表,带头结点
88 DoubleLinkedList() {
89 this(null);
90 }
91
92 //建表,带头结点,表中有一条数据元素
93 DoubleLinkedList(T element) {
94 if(element == null) {
95 head = new Node<T>(element,null,null);
96 head.setRight(head);
97 head.setLeft(head);
98 }else {
99 Node<T> headRight = new Node<T>(element,null,null);
100 head = new Node<T>(null,headRight,headRight);
101 headRight.setLeft(head);
102 headRight.setRight(head);
103 }
104 }
105
106 //清空当前链表
107 public void clear() {}
108
109 //判空表
110 public boolean isEmpty() {
111 return head.getRight() == head;
112 }
113
114 //表长
115 public int Length() {
116 int len = 0;
117 Node<T> temp = head;
118 while(temp.getRight() != head) {
119 len++;
120 temp = temp.getRight();
121 }
122 return len;
123 }
124
125 //取下标index处的数据
126 public T getElement(int index) {
127 if(index <= 0) {
128 return head.getRight().getData();
129 }
130 int len = Length();
131 if(index >= len) {
132 return head.getLeft().getData();
133 }
134 T element = null;
135 if(index > 0 && index < len) {
136 int k = 0;
137 Node<T> temp = head;
138 //此处只能用while不能用if,用错好几次
139 while(k <= index && temp.getRight() != head) {
140 k++;
141 temp = temp.getRight();
142 }
143 element = temp.getData();
144 }
145 return element;
146 }
147
148 //尾添
149 public boolean add(T element) {
150 if(element == null) return false;
151 Node<T> node = new Node<T>(element,head.getLeft(),head);
152 head.getLeft().setRight(node);
153 head.setLeft(node);
154 return true;
155 }
156
157 //首添
158 public boolean addHead(T element) {
159 if(element == null) return false;
160 Node<T> node = new Node<T>(element,head,head.getRight());
161 head.getRight().setLeft(node);
162 head.setRight(node);
163 return false;
164 }
165
166 //表index处,添加新数据element
167 public boolean addByIndex(int index, T element) {
168 if(index <= 0) {
169 return addHead(element);
170 }else if(index >= Length()) {
171 return add(element);
172 }else {
173 int k = 0;
174 Node<T> temp = head;
175 //此处只能用while不能用if,用错好几次
176 while(k <= index && temp.getRight() != head) {
177 k++;
178 temp = temp.getRight();
179 }
180 Node<T> node = new Node<T>(element,temp.getLeft(),temp);
181 temp.getLeft().setRight(node);
182 temp.setLeft(node);
183 }
184 return true;
185 }
186
187 //将参数中的链表添加到当前链表的尾部
188 public boolean add(Listable<T> slist) {
189 if(slist.isEmpty() || slist == null) return false;
190 if(slist instanceof DoubleLinkedList) {
191 DoubleLinkedList<T> list = (DoubleLinkedList<T>)slist;
192 //以下操作影响到了添加的slist表,所以需要将slist表重新备份一个
193 DoubleLinkedList<T> temp = new DoubleLinkedList<T>();
194 for(int i = 0; i < list.Length(); i++) {
195 temp.add(list.getElement(i));
196 }
197 Node<T> node = temp.head;
198 Node<T> nodeLeft = node.getLeft();
199 Node<T> nodeRight = node.getRight();
200 this.head.getLeft().setRight(node.getRight());
201 nodeRight.setLeft(this.head.getLeft());
202 nodeLeft.setRight(this.head);
203 this.head.setLeft(node.getLeft());
204 return true;
205 }else {
206 return false;
207 }
208 }
209
210 //删除下标Index处的数据
211 public T remove(int index) {
212 if(isEmpty()) return null;
213 if(index < 0) {
214 index = 0;
215 }
216 int len = Length();
217 if(index >= len) {
218 //当index大于或等于表长是,默认移走表的最后一个元素,即下标为len-1的数据
219 index = len-1;
220 }
221 T element = null;
222 if(index >= 0 && index < len) {
223 Node<T> temp = head;
224 int k = 0;
225 while(k <= index && temp.getRight() != head) {
226 k++;
227 temp = temp.getRight();
228 }
229 element = temp.getData();
230 temp.getRight().setLeft(temp.getLeft());
231 temp.getLeft().setRight(temp.getRight());
232 temp.setRight(null);
233 temp.setLeft(null);
234 temp = null;
235 }
236 return element;
237 }
238
239 //删除当前链表中所有的数据,只剩头结点
240 public boolean removeAll() {
241 if(isEmpty()) return false;
242 Node<T> temp = head.getRight();
243 while(temp != head) {
244 head.setRight(temp.getRight());
245 temp.getRight().setLeft(head);
246 temp.setLeft(null);
247 temp.setRight(null);
248 temp = head.getRight();
249 }
250 return true;
251 }
252
253 //删除链表中从head开始的第一个element数据
254 public T remove(T element) {
255 if(isEmpty() || element == null) return null;
256 //从表中第一个元素开始比较
257 Node<T> temp = head.getRight();
258 int k=0;
259 while(temp != head) {
260 if(element.equals(temp.getData())) {
261 remove(k);
262 return element;
263 }else {
264 temp = temp.getRight();
265 k++;
266 }
267 }
268 if(k == (Length()-1)) {
269 System.out.println("该链表中没有该数据");
270 }
271 return element;
272 }
273
274 //修改下标index处的数据,并将原始数据返回
275 public T setElement(int index,T element) {
276 if(index < 0 || index >= Length()) return null;
277 Node<T> temp = head;
278 int k = 0;
279 while(k < index && temp.getRight() != head) {
280 k++;
281 temp = temp.getRight();
282 }
283 T tempEle = temp.getData();
284 temp.setData(element);
285 return tempEle;
286 }
287
288 //重写父类toString方法,实际是给list做遍历后将数据打印出来
289 public String toString() {
290 StringBuffer sb = new StringBuffer();
291 /*通过for循环遍历双向循环链表
292 int length = Length();
293 sb.append("[ ");
294 for(int i = 0; i < length; i++) {
295 sb.append(getElement(i)+" ");
296 }
297 sb.append("]");
298 */
299 //从表头开始遍历双向循环链表
300 sb.append("[ ");
301 Node<T> node = head;
302 while(node.getRight() != head) {
303 sb.append(node.getRight().getData()+" ");
304 node = node.getRight();
305 }
306 sb.append("]");
307 return sb.toString();
308 }
309
310 }