循环链表的简介
循环链表本质上和单链表并没有什么不同,准确的说循环链表就是特殊的单链表。
单链表:除了头结点和尾结点每个节点都有且仅有一个前驱和后继。
循环链表:每一个结点都有且仅有一个前驱和后继。
循环链表的特点
不管从任一节点开始,都能遍历整个链表
循环链表的基本操作
1.创建循环链表
从图中我们可以看到循环链表的尾节点直接指向了头结点,所以创建循环链表遵循此规律即可。
在这里我们稍微修改一下,不用头指针,改用尾指针,这样子不管是头结点还是尾节点我们都可以很方便的找到,而不用遍历整个链表。
2.增加元素
增加元素和单链表相同,只需要改变指针即可,我们现在有尾指针,可以直接定位到尾节点,将新结点插在尾节点后面即可。
3.删除元素
从头结点开始遍历,直到找到需要删除的结点,修改指针域即可,但要注意若是删除的结点刚好是尾节点需要将尾指针往前移动一下。
/**
* 结点类
*/
class Entry<T>{
/**
* 数据域
*/
T data;
/**
* 指针域
*/
Entry next;
public Entry(){
this.data = null;
this.next = null;
}
public Entry(T data,Entry<T> next){
this.data = data;
this.next = next;
}
public Entry(T data){
this.data = data;
}
}
/**
* 链表类
*/
class CycleLink<T>{
/**
* 头结点
*/
Entry<T> head = null;
/**
* 尾指针
*/
Entry<T> last = null;
/**
* 链表长度
*/
int size;
public CycleLink(){
head = new Entry();
head.next = head;
last = head;
size = 0;
}
/**
* 增加元素
*/
public void add(T data){
Entry<T> node = new Entry(data);
node.next = last.next;
last.next = node;
last = node;
size++;
}
/**
* 删除元素
*/
public void delete(T data){
Entry p1 = head;
Entry p2 = head.next;
while(p2 != head){
if(p2.data == data){
if(p2 == last){//判断此节点是不是尾节点,如果是,还需要移动尾指针。
last = p1;
}
p1.next = p2.next;
}
p1 = p2;
p2 = p2.next;
size--;
}
}
public void show(){
Entry p = head.next;
while(p != head){
System.out.print(p.data+" ");
p = p.next;
}
System.out.println();
}
}
public class Demo6 {
public static void main(String[] args) {
CycleLink<Integer> link = new CycleLink<Integer>();
link.add(84); link.add(45); link.add(75);
link.add(15); link.add(29); link.add(11);
link.add(23); link.add(29); link.add(7);
link.show(); link.delete(29);
link.show(); link.delete(11);
link.show(); link.delete(7);
link.show();
}
}
运行结果
84 45 75 15 29 11 23 29 7
84 45 75 15 11 23 7
84 45 75 15 23 7
84 45 75 15 23