C語言約瑟夫環經典版--For初學者

這是一個經典的問題,內容是click here。本文章要實現的是:一共n個人,從第k個人開始報數,數到m的淘汰。從他的下一個人接着數,直到剩餘一個人爲止。
首先,生成n個人的單鏈表,並從第k個人開始生成。在這裏插入圖片描述
首尾相接後,如圖:
在這裏插入圖片描述
第一個節點數據元素存的是k,也就是說從第1個開始數到m,
在這裏插入圖片描述
此時q指向m-1,p指向第m個元素。將第p個元素刪除即可,然後循環遍歷,知道最後一個人剩下。
思路就是這樣。
編譯環境爲Code::Blocks,由於能力有限,難免有bug,僅給讀者提供思路。
代碼如下:

#include<stdio.h>
#include<string.h>

typedef int ElemType;

typedef struct node
{
    ElemType data;
    struct node *next;
}LNode;

void Josephus(int n,int m,int k)
{
    LNode *q,*p;
    int i;
    p=(LNode *)malloc(sizeof(LNode));//申請一個新節點
    q=p;
    for(i=1;i<n;i++)        //for循環吧n-1個人排上號
    {
        q->data=k;          //第一個節點爲k,即從k開始
        k=k%n+1;            //避免k=n的情況
        q->next=(LNode *)malloc(sizeof(LNode));
        q=q->next;          //q一直指向最新的節點
    }
    q->data=k;              //q指向第n個人,k也是第n個數
    q->next=p;              //尾指針指向頭結點,形成循環單鏈表
    printf("依次淘汰的人\n");
    while(p->next!=p)       //判斷是否剩餘一個人
    {
        for(i=1;i<m;i++)
        {
            q=p;            //當從循環出來q在m-1處
            p=p->next;      //當從循環出來的時候,p節點在m位置處
        }

        q->next=p->next;//q指向m+1的節點,即淘汰第m個人

        printf("%4d",p->data);
        free(p);
        p=q->next;
    }
    printf("\n剩的最後一人\n");
    printf("%4d",p->data);
}
int main()
{
    int n,m,k;
    printf("輸入人數n,總報數m,開始號k\n");
    scanf("%d%d%d",&n,&m,&k);
    Josephus(n,m,k);
    return 0;
}

運行後結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章