zoukankan      html  css  js  c++  java
  • 一个小笔记(3):约瑟夫环

    什么是约瑟夫环?
    其实百度有说
    http://baike.baidu.com/view/717633.htm

    以一个传说中的问题为例子,提供源代码
    主要是能够通过这个问题,了解如何来操作循环链表


    在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏

    最后输出结果为最后一个存活的人的编号

    // 约瑟夫问题(循环链表).cpp
    // Win32控制台程序
    #include "stdafx.h" 
    #include <stdlib.h> 
    
    typedef struct JOSEPH_NODE 
    { 
        int iNum;   // 编号
        struct JOSEPH_NODE * pNext;
    } JOSEPH_NODE_S; 
    
    // pJosephStart结点的下一个结点就是要杀死的人,删除该结点
    void Delete_Next_Joseph(JOSEPH_NODE_S * pJosephStart) 
    { 
        JOSEPH_NODE_S * pJose = pJosephStart->pNext; 
        pJosephStart->pNext = pJose->pNext; 
        free(pJose); 
    } 
    
    // 释放链表
    void Destroy_Joseph(JOSEPH_NODE_S * pJosephHead) 
    { 
        while (pJosephHead->pNext != pJosephHead) 
        {
            Destroy_Joseph(pJosephHead); 
        } 
        free(pJosephHead);
    } 
    
    // 初始化链表
    int Init_Joseph(int iCount, JOSEPH_NODE_S ** ppJosephHead) 
    { 
        if (iCount < 1)
        { 
            return 0; 
        } 
    
        JOSEPH_NODE_S * pJoseNew; 
        JOSEPH_NODE_S * pJoseCur;
        int iSize = sizeof(JOSEPH_NODE_S); 
        pJoseNew = (JOSEPH_NODE_S *)malloc(iSize); 
    
        if (pJoseNew == nullptr) 
        { 
            return 0; 
        } 
    
        pJoseNew->iNum = 1; 
        pJoseNew->pNext = pJoseNew;
        *ppJosephHead = pJoseNew; 
        pJoseCur = pJoseNew; 
     
        // 链表添加结点
        for (int i = 1; i < iCount; i++) 
        { 
            pJoseNew = (JOSEPH_NODE_S *)malloc(iSize); 
    
            if (pJoseNew == nullptr) 
            { 
                Destroy_Joseph(*ppJosephHead); 
                return 0; 
            } 
    
            pJoseNew->iNum = i + 1; 
            pJoseNew->pNext = *ppJosephHead; 
    
            pJoseCur->pNext = pJoseNew; 
            pJoseCur = pJoseNew; 
        } 
    
        return 1;
    } 
    
    // 得到最后一个存活的人
    // iCount:总人数
    // iSkip:每隔多少个人就杀死一个人
    int GetLastNode_Joseph(int iCount, int iSkip) 
    { 
        JOSEPH_NODE_S * pJoseph = nullptr; 
        JOSEPH_NODE_S * pJoseStart = nullptr; 
    
        if (Init_Joseph(iCount, &pJoseph) != 1) 
        { 
            printf("初始化失败
    ");
            return 0; 
        }
        pJoseStart = pJoseph; 
    
        // 每隔0个人杀死,最后一个人存活
        if (iSkip == 0) 
        { 
            while (pJoseStart->pNext->pNext != pJoseStart) 
            { 
                Delete_Next_Joseph(pJoseStart); 
            } 
    
            printf("Final Num: %d
    
    ", pJoseStart->pNext->iNum); 
            free(pJoseStart->pNext); 
            free(pJoseStart); 
    
            return 1; 
        } 
    
        // 每隔iSkip个人杀死一个人
        // 直到剩下1个人,剩下最后一个结点的pNext会指向自己
         while (pJoseStart->pNext != pJoseStart) 
        { 
            for (int i = 1; i < iSkip; i++) 
            { 
                pJoseStart = pJoseStart->pNext; 
            } 
    
            Delete_Next_Joseph(pJoseStart); 
    
            pJoseStart = pJoseStart->pNext; 
        } 
    
        printf("Final Num: %d
    
    ", pJoseStart->iNum); 
    
        free(pJoseStart); 
    
    
        return 1; 
    
    } 
    
    int main() 
    { 
        GetLastNode_Joseph(41, 2); 
    
        return 0; 
    
    }
  • 相关阅读:
    idea快捷的输出常用语句
    OneinStack基础搭建typecheo轻量级博客
    自动化框架介绍及使用
    jenkins配置自动化
    selenium模拟鼠标点击
    Linux下安装nginx
    解决“chrome正受到自动测试软件的控制”信息栏显示问题
    Git 常用操作
    ZendStudio自定义代码补全,自定义代码段
    07-python之装饰器
  • 原文地址:https://www.cnblogs.com/recordprogram/p/5656736.html
Copyright © 2011-2022 走看看