數據結構筆記——雙向循環鏈表示例 約瑟夫環


/*
利用雙向鏈表解決約瑟夫環問題(也可以使用循環鏈表)
問題描述:
    將n個人圍成一圈開始報數,每次報到m的人出列,它的下一個
    人從1開始重新報數,直到所有玩家出列。 
解決思路,使用一個雙向循環鏈表模擬整個游戲成員,每一個節點
代表一玩家。 
*/

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

// 雙向鏈表類型定義
typedef struct NODE
{
    int data;              // 數據域 
    struct NODE * next;    // 儲存前驅地址 
    struct NODE * prior;   // 儲存此節點的后一個節點的地址 
}Node, * pNode;

// 雙向循環鏈表的創建
pNode Create_DCList(int len);
// 在長度為n的雙向循環鏈表上,報數為m的玩家出列
void Josephus(pNode pHead, int n, int m, int k);

int main(void)
{
    pNode pHead;
    int n, k, m;
    printf("輸入玩家個數 n = ");
    scanf("%d", &n);
    printf("輸入開始報數的序號 k = ");
    scanf("%d", &k);
    printf("報數為 m 的人出列 m = ");
    scanf("%d", &m);
    pHead = Create_DCList(n);
    Josephus(pHead, n, m, k); 
    
    return 0;
}

// 雙向循環鏈表的創建
pNode Create_DCList(int len)
{
    pNode pHead = NULL;
    pNode s, q;
    int i;
    for (i = 1; i <= len; ++i)
    {
        s = (pNode)malloc(sizeof(Node));
        if (NULL == s)
        {
            printf("動態內存分配失敗!\n");
            exit(-1);
        }
        s->data = i;
        s->next = NULL;
        
        // 將新節點插入雙向循環鏈表
        if (NULL == pHead)
        {
            pHead = s;
            s->prior = pHead;
            s->next = pHead;
        } 
        else
        {
            s->next = q->next;
            q->next = s;
            s->prior = q;
            pHead->prior = s;
        }
        // q始終指向鏈表最后一個節點
        q = s; 
    }
    
    return pHead;
}

// 在長度為n的雙向循環鏈表上,報數為m的玩家出列
void Josephus(pNode pHead, int n, int m, int k)
{
    pNode p, q;
    int i;
    p = pHead;
    // 從第k個人開始報數 
    for (i = 1; i < k; ++i)
    {
        q = p;
        p = p->next;
    }
    while (p->next != p) // 當只剩下一個節點時停止循環 
    {
        for (i = 1; i < m; ++i)
        {
            q = p;
            p = p->next; 
        }
        q->next = p->next;  // 將p節點刪除
        p->next->prior = q;
        printf("%4d", p->data);  // 輸出出列的玩家 
        free(p);
        p = q->next;     
    }
    printf("%4d\n", p->data);
    free(p);
    p = NULL;
    
    return;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM