约瑟夫环问题(C语言循环链表)

一:问题描述

约瑟夫环问题是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列,他的下一个人又开始报数,数到m的那个人又出列,依次规律重复下去,圆桌周围的人全部出列。

二:算法原理

约瑟夫环运作如下:

1:一群人围坐在一起成环状

2:从某个编号开始报数(如:k)

3:数到某个数(如:m)的时候,此人出列,下一个人重新报数

4:一直循环,直到所有人出列,约瑟夫环出列

三:具体代码实现如下:(保留了最后一个编号)

#include<stdio.h>  
#include<stdlib.h>  

typedef struct Node{  
    int data;  
    struct Node* next;  
}LNode,*LinkList;  

void Josephus(int n, int m, int k)  
{  
    LinkList p = NULL, x = NULL, list = NULL;  
    int i;  
    for(i = 1; i <= n; i++)  
    {  
        p = (LNode*)malloc(sizeof(LNode));//向系统申请内存  
        if (p==NULL) {//确保指针使用前为非空指针,当p为空指针时结束程序  
            printf("分配失败!");  
            exit(1);  
        }  
        p->data = i;//编号  
        if(list == NULL)  
            list = p;  
        else  
            x->next = p;//将x和p节点串起来  
            x = p;//x指针后移  
    }  
    p->next = list;//建立一个循环链表  
    p = list;//p指针后移  
    for(i = 1; i < k; i++)  
    {  
        x = p;  
        p = p->next;  
    }            //此时p指向第1个出发点  
    while(p->next != p)  
    {  
        for(i=1; i<m; i++)  
        {  
            x = p;  
            p = p->next;  
        }                    //p指向第m个结点,x指向第m-1个结点  
       x->next = p->next;              //删除第m个结点  
        printf("%d号自杀\n", p->data);         //输出一个结点编号  
        free(p);                        //释放被删除结点的空间  
        p = x->next;                    //p指向新的出发点  
    }  
    printf("最后能生存下来的为%d号\n", p->data);   //输出最后那个结点的编号  
    free(p);  
}  
int main()  
{  
    int m,k,n;  
    printf("请输入总人数:");  
    scanf("%d",&n);  
    printf("请输入从第几人报数:");  
    scanf("%d",&k);  
    printf("请输入间隔人数:");  
    scanf("%d",&m);  
    Josephus(n, m, k);  
}  




猜你喜欢

转载自blog.csdn.net/leikun153/article/details/80167167