日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

循环链表应用——约瑟夫置换

發布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 循环链表应用——约瑟夫置换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

約瑟夫問題

介紹

約瑟夫問題,又稱約瑟夫置換丟手絹問題

一般形式

(本部分內容來自百度百科)

約瑟夫問題是個有名的問題:N個人圍成一圈,從第一個開始報數,第M個將被殺掉,最后剩下一個,其余人都將被殺掉。例如N=6,M=5,被殺掉的順序是:5,4,6,2,3。

代碼

問題描述

本文以以下問題為例

編號為1-10的10 個人圍成一圈,從第一個開始報數,第9個被淘汰出圈,剩下的組成新的圈。依次這樣下去,求最后一個人的編號

解決

注意:該段代碼與上篇文章——《 循環鏈表定義及操作 》相接

//解答約瑟夫問題 bool Joseph(LinkList* &L, int interval) {LinkList *p = L, *q;int i = 0, j = 0;int times = 0; //當前輪數int num = 0;if(!L || p->next == L){cout << "鏈表為空\n";return false;}if(interval < 1){cout << "報數淘汰口令不能小于1\n";return false;}do{i += interval;//找查第i個結點,p指向該結點的上一個結點while(p->next){if(p->next != L){//如果不是頭結點的話j++;}if(j >= i) break;p = p->next;}times++;q = p->next; //臨時保存被刪結點以備釋放空間num = q->data;cout << "當前結點:" << q->data<< " 上一個結點:" << p->data<<" 下一個結點:" << q->next->data<< endl;p->next = q->next;delete q; //釋放被刪除結點內存LinkListPrint(L);}while(L->next != L); //鏈表不為空,繼續報數cout << "最后一個出圈者的編號" << num << endl;return true; }

完整代碼

代碼

#include <iostream> #include <string>using namespace std;typedef struct _LinkNode {int data;struct _LinkNode *next; }LinkList;bool InitList(LinkList* &L) {L = new LinkList;if(!L) return false;L->next = L;L->data = 0;return true; }bool ListInsert_back(LinkList* &L, LinkList *node) {LinkList *last = NULL;if(!L || !node) return false;if(L == L->next){//頭結點指針指向了自己(鏈表只有頭結點)node->next = L;L->next = node;}else{//非空的循環鏈表last = L->next;//尋找尾結點(指向頭結點的結點)while(last->next != L){last = last->next;}node->next = L;last->next = node;}return true; }void LinkListPrint(LinkList *L) {LinkList *p;if(!L || L == L->next){cout << "鏈表為空\n";return;}p = L->next;while(p != L){cout << p->data << "\t";p = p->next;}cout << endl; }//解答約瑟夫問題 bool Joseph(LinkList* &L, int interval) {LinkList *p = L, *q;int i = 0, j = 0;int times = 0; //當前輪數int num = 0;if(!L || p->next == L){cout << "鏈表為空\n";return false;}if(interval < 1){cout << "報數淘汰口令不能小于1\n";return false;}do{i += interval;//找查第i個結點,p指向該結點的上一個結點while(p->next){if(p->next != L){//如果不是頭結點的話j++;}if(j >= i) break;p = p->next;}times++;q = p->next; //臨時保存被刪結點以備釋放空間num = q->data;cout << "當前結點:" << q->data<< " 上一個結點:" << p->data<<" 下一個結點:" << q->next->data<< endl;p->next = q->next;delete q; //釋放被刪除結點內存LinkListPrint(L);}while(L->next != L); //鏈表不為空,繼續報數cout << "最后一個出圈者的編號" << num << endl;return true; }int main() {LinkList *L, *s;int i = 0;if(InitList(L)){cout << "創建一個空的循環鏈表\n";}else{exit(-1);}cout << "尾插10個元素...\n";while((++i)<=10){s = new LinkList;s->data = i;s->next = NULL;if(ListInsert_back(L, s)){cout << "success\n";}else{cout << "default\n";}}LinkListPrint(L);Joseph(L,9);return 0;}

輸出結果

注:0為頭結點的數據,該結點并不計入約瑟夫環中(但最后也將其刪除銷毀鏈表釋放內存)

創建一個空的循環鏈表 尾插10個元素... success success success success success success success success success success 1 2 3 4 5 6 7 8 9 10 當前結點:9 上一個結點:8 下一個結點:10 1 2 3 4 5 6 7 8 10 當前結點:8 上一個結點:7 下一個結點:10 1 2 3 4 5 6 7 10 當前結點:10 上一個結點:7 下一個結點:0 1 2 3 4 5 6 7 當前結點:2 上一個結點:1 下一個結點:3 1 3 4 5 6 7 當前結點:5 上一個結點:4 下一個結點:6 1 3 4 6 7 當前結點:3 上一個結點:1 下一個結點:4 1 4 6 7 當前結點:4 上一個結點:1 下一個結點:6 1 6 7 當前結點:1 上一個結點:0 下一個結點:6 6 7 當前結點:6 上一個結點:0 下一個結點:7 7 當前結點:7 上一個結點:0 下一個結點:0 鏈表為空 最后一個出圈者的編號7

總結

以上是生活随笔為你收集整理的循环链表应用——约瑟夫置换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。