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


    /*
    利用双向链表解决约瑟夫环问题(也可以使用循环链表)
    问题描述:
        将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("动态内存分配失败!
    ");
                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
    ", p->data);
        free(p);
        p = NULL;
        
        return;
    }
  • 相关阅读:
    第二百一十五节,jQuery EasyUI,DateBox(日期输入框)组件
    第二百一十四节,jQuery EasyUI,Calendar(日历)组件
    onethink 系统函数中 生成随机加密key
    本地开发 localhost链接数据库比127.0.0.1慢
    仿写thinkphp的I方法
    判断数组中有没有某个键 isset 和 array_key_exists 的效率比较
    jquery实时监听某个文本框的输入事件
    js数组去重
    thinkphp3.2.3 版本使用redis缓存的时候无法使用认证
    javascript中使用md5函数
  • 原文地址:https://www.cnblogs.com/lnlin/p/6725216.html
Copyright © 2020-2023  润新知