約瑟夫環的普通解法及優化

約瑟夫環問題的普通解法很簡單,就是不斷遍歷循環鏈表,刪除節點,假如有n個人,等到第m個人報數時殺掉這個人,即刪除這個節點,直到只剩下一個人。

struct Node
{
    Node(int data)
        :_data(data)
        ,_pNext(NULL)
    {}

    int _data;
    Node* _pNext;
};

1,普通解法,時間複雜度爲O(n*m),因爲刪掉一個節點需要遍歷 m 次;
代碼實現

Node* josephuskill1(Node* pHead,int m)//第m個人被殺掉
{
    if(pHead == NULL)
        return NULL;

    //構環
    Node* pCur = pHead;
    while(pCur->_pNext)
        pCur = pCur->_pNext;
    pCur->_pNext = pHead;

    pCur = pHead;
    int num = m;
    Node* pRev;
    while(pCur->_pNext != pCur)//只剩下一個節點
    {
        num = m;
        while(--num)
        {
            pRev = pCur;
            pCur = pCur->_pNext;
        }
        pRev->_pNext = pCur->_pNext;//刪除節點
    }

    pHead = pCur;
    return pHead;
}

測試代碼

void funtest1()
{
    Node node1(1);
    Node node2(2);
    Node node3(3);
    Node node4(4);
    Node node5(5);

    node1._pNext = &node2; 
    node2._pNext = &node3;
    node3._pNext = &node4;
    node4._pNext = &node5;

    Node* ret = josephuskill1(&node1,3);
}
int main()
{
    funtest1();
    getchar();
    return 0;
}

2.約瑟夫環的優化,時間複雜度爲O(n)

思路:我們直接直到最後存活的節點,然後刪除其餘節點,保存這個節點;
問題是:我們怎樣直接找到該節點呢?
這裏寫圖片描述

代碼實現:

int GetLive(int i,int m)//i是鏈表中總的節點個數,m是第m個報數的人被殺掉,返回存活的新的編號
{
    if(i == 1)//當鏈表中只剩下一個節點的時候,此時該節點對應的新編號就是1
        return 1;
    return (GetLive(i-1,m)+m-1)%i+1;//遞歸,當i=2時,我們得到存活節點(i=2)對應兩個節點時的編號,直到i = N 時
}


Node* josephuskill2(Node* pHead,int m)//第m個人被殺掉
{
    if(pHead == NULL)
        return NULL;

    //構環
    Node* pCur = pHead;
    while(pCur->_pNext)
        pCur = pCur->_pNext;
    pCur->_pNext = pHead;


    int num = 1;
    pCur = pHead;

    while(pCur->_pNext != pHead)
    {
        num++;//獲取鏈表中節點的個數
        pCur = pCur->_pNext;
    }
    int retnum = GetLive(num,m);//得到的retnum就是存活節點在總數爲num個節點的編號

    //根據編號找到節點
    while(--retnum)
    {
        pHead = pHead->_pNext;
    }
    pHead->_pNext = pHead;
    return pHead;
}

測試代碼:

void funtest1()
{
    Node node1(1);
    Node node2(2);
    Node node3(3);
    Node node4(4);
    Node node5(5);

    node1._pNext = &node2; 
    node2._pNext = &node3;
    node3._pNext = &node4;
    node4._pNext = &node5;

    Node* ret = josephuskill2(&node1,3);
}
int main()
{
    funtest1();
    getchar();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章