單鏈表實現約瑟夫環

大家對約瑟夫環是比較陌生的,但是對於大多數人來說,丟手絹卻一點都不陌生,其實約瑟夫環和丟手絹差不多。

約瑟夫環

約瑟夫環(約瑟夫問題)是一個數學的應用問題:已知n個人(以編號1,2,3…n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。通常解決這類問題時我們把編號從0~n-1,最後結果+1即爲原問題的解。
詳見百度百科約瑟夫環.
在本篇博客中,我將是以一個單鏈表圍成一個環,然後從第一個結點開始報數,當數到3的時候的那個結點就被拋出,然後從下一個開始又重新從1開始繼續報數,從而留下最後一個結點,就是約瑟夫點(我自己瞎猜的);
下面是我畫的一個對於一共有8個結點的環,每次報到3的時候就刪除這個結點的展示圖:
這裏寫圖片描述

第一步:從1開始報數爲3的時候就刪除3號結點
第二步:從4號結點開始報數,當爲3的時候刪除6號結點;
第三步:從7號結點開始報數,當爲3的時候刪除1號結點;
第四步:從2號結點開始報數,當爲3的時候刪除5號結點;
第五步:從7號結點開始報數,當爲3的時候刪除2號結點;
第六步:從4號元素開始報數,當爲3的時候刪除8號結點;
第七步:又從4號開始報數,當爲3的時候刪除4號結點,此時鏈表中只有一個7號結點,所以最後的結點就是7號結點;

大概思路我們都有了,所以我們事先代碼如下:

#include<iostream>
#include<assert.h>
using namespace std;

typedef int DataType;
typedef struct Node
{
    DataType _data;
    struct Node* _pNext;
}Node, *PNode;

Node* BuyNode(DataType data) //創建新結點
{
    PNode newNode = NULL;
    newNode = (PNode)malloc(sizeof(Node));
    if (NULL == newNode)
    {
        printf("out of memory\n");
        return NULL;
    }
    else
    {
        newNode->_data = data;
        newNode->_pNext = NULL;
    }
    return newNode;
}

void InitList(PNode* pHead)  //初始化鏈表
{
    assert(pHead);
    *pHead = NULL;
}

void PushBack(PNode* pHead, DataType data) //尾插
{
    assert(pHead);
    if (*pHead == NULL)
        *pHead = BuyNode(data);
    else
    {
        PNode pPreNode = *pHead;
        PNode pCurNode = BuyNode(data);
        while (pPreNode->_pNext)
            pPreNode = pPreNode->_pNext;
        pPreNode->_pNext = pCurNode;
    }
}

PNode Front(PNode pHead) //返回第一個結點
{
    if (NULL == pHead)
        return NULL;
    PNode pPreNode = pHead;
    return pPreNode;
}

PNode Back(PNode pHead) //返回最後一個結點
{
    if (NULL == pHead)
        return NULL;
    PNode pPreNode = pHead;
    while (pPreNode->_pNext && pPreNode)
        pPreNode = pPreNode->_pNext;
    return pPreNode;
}

PNode JosephCircle(PNode* pHead, int m)//約瑟夫環
{
    int count = m;
    PNode pPreNode = *pHead;
    PNode pCurNode = NULL;
    assert(pHead);
    if (NULL == *pHead)
        return NULL;
    while (pPreNode->_pNext != pPreNode)
    {
        count = m;
        while (--count)
        {
            pCurNode = pPreNode;
            pPreNode = pPreNode->_pNext;
        }
        pCurNode->_pNext = pPreNode->_pNext;
        free(pPreNode);
        pPreNode = pCurNode->_pNext;
    }
    return pPreNode;
}

int main()
{
    PNode pHead, pBackNode, pFrontNode;
    PNode tmp1;
    InitList(&pHead);
    PushBack(&pHead, 1);
    PushBack(&pHead, 2);
    PushBack(&pHead, 3);
    PushBack(&pHead, 4);
    PushBack(&pHead, 5);
    PushBack(&pHead, 6);
    PushBack(&pHead, 7);
    PushBack(&pHead, 8);

    pBackNode = Back(pHead);
    pFrontNode = Front(pHead);
    pBackNode->_pNext = pFrontNode;
    tmp1 = JosephCircle(&pHead, 3);
    cout << tmp1->_data << endl;
    return 0;
}

這裏寫圖片描述

發佈了63 篇原創文章 · 獲贊 50 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章