循环链表
循环链表的结构和单链表结构一样,只是单链表的尾结点的next指针指向null,循环链表的尾结点的next指针指向头节点,仅此而已。
图示:
循环链表的增删查改都同单链表一样,只是在遍历这块有一定小猫腻。
循环链表的遍历
- 第一种:
public static void printList(Node head){
Node cur = head;
while(cur.next != head){
System.out.print(cur.data + " 、");
cur = cur.next;
}
}
但很容易发现这种写法循环中没有输出最后一个结点的内容,因为当cur.next == head的时候刚好来到最后一个结点,此时并不会再进入循环。因此我们可以单独加一句来输出最后一个结点的内容。
- 改进版:
public static void printList(Node head){
Node cur = head;
while(cur.next != head){
System.out.print(cur.data + " 、");
cur = cur.next;
}
System.out.println(cur.data); // 专门输出最后一个结点的内容
}
- 第二种:
public static void printList(Node head) {
Node cur = head;
while (cur != head) {
System.out.println(cur.data + "、");
cur = cur.next;
}
}
感觉没有问题,但仔细一想,这个循环更加离谱,因为循环刚开始的判断条件就不成立,因此不会进入这个循环内部。即一个结点也没有输出出来。当然也可以首先输出头节点的内容,然后cur = cur.next,这样再利用这个循环就ok了。
- 改进版:
public static void printList(Node head) {
Node cur = head;
System.out.println(cur.data); // 首先处理掉第一个结点
cur = cur.next; // cur指向第二个结点
while(cur != head){
System.out.println(cur.data + "、");
cur = cur.next;
}
}
巧用do…while 循环
public static void printList(Node head) {
Node cur = head;
do{
System.out.print(cur.data + "、");
cur = cur.next;
}while(cur != head);
}
这样就能完美的遍历循环链表。这是因为do…while循环不管条件成立与否首先会执行一次循环体,弥补了while循环处理此问题时的弊端。