循环链表与约瑟夫环

循环链表其实就是将单链表(或者双向链表首尾相连)构成的,我认为比较简单的循环链表创建方法(这个是带头结点):
(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来解决删除的操作,这样在删除一个元素后,指针还定位在他之前的位置上,然后从这个位置开始继续循环直到结束。

猜你喜欢

转载自blog.csdn.net/cprimesplus/article/details/82596208