約瑟夫環問題,是一個經典的循環鏈表問題,題意是:已知 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; }