循环链表其实就是将单链表(或者双向链表首尾相连)构成的,我认为比较简单的循环链表创建方法(这个是带头结点):
(1)创建单链表并记录最后一个点,最后将最后一个点指向head即可。
很简单,只需要在while循环后加上一句pend->next=head;即可
代码:
NODE *createlink()
{
NODE *head,*pnew,*pend;
int n;
head=(NODE *)malloc(sizeof(NODE));
head->pre=NULL;
head->next=NULL;
pend=head;
scanf("%d",&n);
while(n>=0)
{
pnew=(NODE *)malloc(sizeof(NODE ));
pnew->pre=pend;
pnew->next=NULL;
pnew->num=n;
pend->next=pnew;
pend=pnew;
scanf("%d",&n);
}
pend->next=head;
return head;
}
(2)还有一种方法,其实大体上的方法类似:
首先创建一个节点,并让这个节点作为头节点,因为最初的时候没有新的元素添加,因此让头节点指向自己,自身成环。
head->num=num;
head->next=head;
而后就可以进入添加元素的环节,这里创建的节点与上面不太相同,直接为t->next开辟空间并让t到下一个位置,为这个点赋值后,再让这个点的next指向head即可。图示:
可以看到,单个元素时自身成环,因为head的位置不能变,因此我们使用一个指针来代替head的移动。给新的单元赋值之前,需要将指针挪到下一个单位,方便后边的t->next=head的操作。
约瑟夫环:
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
知道循环链表的创建,再来看约瑟夫环问题,不妨把此问题放到循环链表中来解决,最初环上有9个数,最后剩余元素为1个时游戏结束,因此:
while(t!=t->next)
{
//blabla~~
}
假如想要每过M个点删除一个元素,即123456789->1234 6789->2346789->…..
那么我们可以让指针每次都遍历到要删除元素的前一个元素,利用操作:x->next=x->next->next来解决删除的操作,这样在删除一个元素后,指针还定位在他之前的位置上,然后从这个位置开始继续循环直到结束。