数据结构笔记——双向循环链表示例 约瑟夫环

/*
利用双向链表解决约瑟夫环问题(也可以使用循环链表)
问题描述:
    将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;
}

 

posted @ 2017-04-17 22:15  荒唐了年少  阅读(3776)  评论(0编辑  收藏  举报