目录
1,什么是循环链表
循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。
- 下面使用一张说明什么是循环链表:循环链表在逻辑上形成的是一个环,是单链表的一种改进,在单链表的基础上面,把最后一个节点的next域指向头结点,这样在逻辑上就可以形成一个环状的链表,从链表的任何一个节点开始,都可以访问到整个的链表元素。
2,循环链表的实现
2.1,循环链表节点的定义
class Cnode{
private int data;
public Cnode next;
public Cnode(int data) {
this.data = data;
}
public int getData() {
return data;
}
@Override
public String toString() {
return "Cnode{" +
"data=" + data +
'}';
}
}
2.2,循环链表的实现
2.2.1,定义一个循环链表
class CLinkedList{
private Cnode head;//头指针
private Cnode tail;//尾指针
public CLinkedList(){
head=new Cnode(-1);
tail=new Cnode(-1);
head.next=head;//形成一个环
tail=head;//尾指针指向头
}
public Cnode getHead() {
return head;
}
public Cnode getTail() {
return tail;
}
}
2.2.2,向循环链表末尾添加一个元素
/**
* 向循环链表中添加一个节点,添加在尾部
* @param cnode 添加的节点
* 链表的尾指针永远指向第一个元素(也就是头指针的下一个元素
*/
public void addCnode(Cnode cnode){
//说明此循环链表是空
if(head.next == head){
head.next=cnode;
tail=cnode;
tail.next=head.next;
}else {
//此循环链表不空
tail.next=cnode;
cnode.next=head.next;
tail=cnode;
}
}
2.2.3,打印循环链表
// 打印循环链表
void printCLinkedlist(){
Cnode cnode=this.head.next;
boolean flag=true;
while (flag){
System.out.print(cnode.getData()+" ");
cnode=cnode.next;
if(cnode.next== head.next){
System.out.print(cnode.getData());
flag=false;
}
}
}
2.2.4,根据元素值删除循环链表中的一个节点
/**
* 根据元素的值,删除循环链表中的一个元素
* @param value 要删除节点的值
* @return 删除成功返回true,删除失败返回false
*/
public boolean deleteValue(int value){
// 首先判断链表是否是空链表
Cnode cnode=this.head;
// 链表空,删除不成功
if(cnode.next == head)
return false;
Cnode cnode1=this.head.next;
while (cnode1.next != head)
{
// 找到需要删除的元素
if(cnode1.getData() == value){
cnode.next=cnode1.next;
return true;
}else {
cnode=cnode.next;
cnode1=cnode1.next;
}
}
return false;
}
2.2.5,约瑟夫环问题的实现
/**
* m个人围成一个圈,指定一个数字n,从第一个人开始报数,每轮报到n的选手出局,
* 由下一个人接着从头开始报,最后一个人是赢家。其中m>1,n>2。
* @param cnode 循环链表的头结点
* @param n 随机数字n,其中n>2
*/
public static void JosephCircle(Cnode cnode,int n){
Cnode cnode1=cnode.next;
Cnode cnode2=cnode;
int k=1;
while (cnode1!= cnode2){
while (k<=n-1){
cnode1=cnode1.next;
cnode2=cnode2.next;
k++;
}
//跳出循环,说明cnode1所指的节点要出队列
System.out.println(cnode1.getData()+" ");
cnode1=cnode1.next;
cnode2.next=cnode1;
k=1;
}
System.out.println(cnode1.getData()+" ");
}
3,测试代码
public class ClinkedListDemo {
public static void main(String[] args) {
CLinkedList cLinkedList=new CLinkedList();
cLinkedList.addCnode(new Cnode(1));
cLinkedList.addCnode(new Cnode(2));
cLinkedList.addCnode(new Cnode(3));
cLinkedList.addCnode(new Cnode(4));
cLinkedList.addCnode(new Cnode(5));
cLinkedList.addCnode(new Cnode(6));
cLinkedList.printCLinkedlist();
System.out.println();
//JosephCircle(cLinkedList.getHead(),2);
// 删除一个元素
cLinkedList.deleteValue(3);
cLinkedList.printCLinkedlist();
}
-
结果展示