約瑟夫環(循環鏈表)


約瑟夫環問題,是一個經典的循環鏈表問題,題意是:已知 n 個人(分別用編號 1,2,3,…,n 表示)圍坐在一張圓桌周圍,從編號為 k 的人開始順時針報數,數到 m 的那個人出列;他的下一個人又從 1 開始,還是順時針開始報數,數到 m 的那個人又出列;依次重復下去,直到圓桌上剩余一個人。

 

#include <iostream>

using namespace std;

struct person {
    int number;
    person *next;
};

person* initLink(int n) {
    person* head = new person;//定義首元節點
    head->number = 1;
    head->next = NULL;
    person* temp = head;
    for (int i = 2; i <= n; ++i) {//定義后面n-1個節點
        person* body = new person;
        body->number = i;
        body->next = NULL;
        temp->next = body;
        temp = temp->next;
    }
    temp->next = head;//首尾相連

    return head;
}

void FindAndDelete(person* head, int n, int num) {
    person* temp = head;
    while (temp->next != head) {//定位到首元節點前一節點
        temp = temp->next;
    }
    person* temp2 = head;
    while (temp2->number != n) {//定一個指針指向起始節點,一個定位到起始節點前一節點,為刪除節點准備
        temp = temp2;
        temp2 = temp2->next;
    }
    while (temp2->next != temp2) {//當一個循環鏈表的節點->next指向自身,說明只剩一個節點
        for (int i = 1; i < num; ++i) {//一個節點定位到數到num的節點,一個定位到前一節點
            temp = temp2;
            temp2 = temp->next;
        }
        temp->next = temp2->next;//刪除num節點
        cout << "序號為:" << temp2->number << "出列" << endl;//刪除的節點為出列序列
        delete temp2;
        temp2 = temp->next;//從下一節點繼續開始
    }
    cout << "最后剩下的同學序列是:" << temp2->number << endl;
    delete temp2;
}

int main()
{
    int n, k, num;
    cout << "請輸入幾位同學:";
    cin >> n;
    person* stu = initLink(n);
    cout << "請輸入起始序列號(1~" << n << "):";
    cin >> k;
    cout << "請輸入數到幾出列:";
    cin >> num;
    FindAndDelete(stu, k, num);

    system("PAUSE");
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM