循环单链表图示

21-咸鱼学Java-Java中的循环单链表_System


代码

/**
* 循环单链表
* @author 焦焱
*
*/
public class LoopLink {
class Entry{
/**
* 数据域
*/
int data;
/**
* 指向下一个节点的地址域
*/
Entry next;
/**
* 有参数的构造方法
* @param data
*/
public Entry(int data) {
this.data = data;
this.next = null;
}
/**
* 无参数构造方法
*/
public Entry()
{
this(-1);
}
}
/**
* 头结点
*/
private Entry head = null;
/**
* 初始化循环链表
*/
public LoopLink() {
//new 头结点
this.head = new Entry();
//因为是循环链表所以头结点的next必须等于自己,形成一个一元环
this.head.next = this.head;
}
/**
* 头插法
* @param val 数据
*/
public void insertHead(int val)
{ //new一个新的节点
Entry entry = new Entry(val);
//当前节点的后继等于头结点的后继
entry.next = this.head.next;
//头结点的后继等于新节点
this.head.next = entry;
}
/**
* 尾插法
* @param val
*/
public void insertTail(int val)
{ //获得头结点
Entry temp = this.head;
//new一个新的节点
Entry entry = new Entry(val);
//一直循环直到循环到最后一个节点
while(temp.next != this.head) {
temp = temp.next;
}
//新节点的next等于最后一个节点的后继,即头结点 此处等于this.head也可
entry.next = temp.next;
//最后一个节点的后继等于新节点
temp.next = entry;
}
/**
* 删除一个元素
* @param val
*/
public boolean deleteVal(int val)
{ //慢引用
Entry t1 = this.head;
//快引用
Entry t2 = this.head.next;
//循环直到再次到头结点,即把整个循环链表遍历一遍
while(t2 != this.head)
{
//当找到和val相等的节点, t1就在需要删除节点的前面
if(t2.data == val)
{
//只需要t1的后继等于t2的后继
t1.next = t2.next;
return true;
}
else
{
//如果不相等两个引用一起走
t1 = t1.next;
t2 = t2.next;
}
}
return false;
}
/**
* 删除循环单链表中所有当前元素
* @param val 元素
* @return
*/
/**
* @param val
*/
public void deleteAllVal(int val)
{
Entry t1 = this.head;
Entry t2 = this.head.next;
while(t2 != this.head)
{
if(t2.data == val)
{
t1.next = t2.next;
//其余同上,此处因为要删除所有的值为val的元素
//所以当删除一个以后需要继续往下走。即t2需要继续走到t1的前面
t2 = t1.next;
}
else
{
t1 = t1.next;
t2 = t2.next;
}
}
}

/**
* 获得循环单链表的长度
* @return
*/
public int getLoopLinkLength()
{
int count = 0;
Entry t = this.head;
//循环直到再次碰到头结点
while(t.next != this.head)
{
count++;
t = t.next;
}

return count;
}
/**
* 判断循环单链表是否为空
* @return
*/
public boolean isEmpty()
{ //直接判断头结点的后继是不是头结点本身
return this.head.next==this.head?true:false;
}
/**
* 打印循环单链表
*/
public void show()
{ //先进行判定链表是否为空
if(isEmpty())
{
System.out.println("链表为空");
return;
}
Entry t = this.head.next;
//否则遍历打印即可
while(t != this.head)
{
System.out.print(t.data+" ");
t = t.next;
}
System.out.println();
}
}

测试

public static void main(String[] args) {
LoopLink t = new LoopLink();
System.out.println("插入之前是否为空:"+t.isEmpty());
int insertLength = 10;
for (int i = 0; i < insertLength; i++) {
t.insertHead(i);
}
t.insertHead(5);
t.insertHead(5);
System.out.println("长度:"+t.getLoopLinkLength());
t.show();
System.out.println("删除一个5:"+t.deleteVal(5));
t.show();
t.deleteAllVal(5);
t.show();
}

结果
​​​插入之前是否为空:true
长度:12
5 5 9 8 7 6 5 4 3 2 1 0
删除一个5:true
5 9 8 7 6 5 4 3 2 1 0
9 8 7 6 4 3 2 1 0​