版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p> 用雙向循環(huán)鏈表求解約瑟夫環(huán)</p><p><b> 學(xué)校:東北大學(xué)</b></p><p> 專業(yè):計算機(jī)科學(xué)與技術(shù)</p><p><b> 1.問題描述</b></p><p> Josephus排列問題定義如下:假設(shè)n個競賽者排成一個環(huán)形。給定一個正整數(shù)m≤n,
2、從第1人開始,沿環(huán)計數(shù),第m人出列。這個過程一直進(jìn)行到所有人都出列為止。最后出列者為優(yōu)勝者。全部出列次序定義了1,2,…n的一個排列。稱為(n,m)Josephus排列。例如,(7,3)Josephus排列為3,6,2,7,5,1,4。</p><p><b> 【實(shí)驗(yàn)要求】</b></p><p> 設(shè)計求解Josephus排列問題程序。</p>
3、<p> ?。?)采用順序表、單鏈表或雙向循環(huán)鏈表等數(shù)據(jù)結(jié)構(gòu)。</p><p> ?。?)采用雙向循環(huán)鏈表實(shí)現(xiàn)Josephus排列問題,且奇數(shù)次順時針輪轉(zhuǎn),偶數(shù)次逆時針輪轉(zhuǎn)。</p><p> ?。?)推薦采用靜態(tài)鏈表實(shí)現(xiàn)Josephus排列問題。</p><p><b> 2.需求分析</b></p><p&g
4、t; 本程序要求根據(jù)輸入的人數(shù)n和給定的正整數(shù)m,求得約瑟夫排列,且奇數(shù)次順時針輪轉(zhuǎn),偶數(shù)次逆時針輪轉(zhuǎn)。故可利用雙向循環(huán)鏈表建立存儲結(jié)構(gòu),利用雙向循環(huán)鏈表的遍歷與刪除操作實(shí)現(xiàn)功能要求。</p><p><b> 3.概要設(shè)計</b></p><p> 1.抽象數(shù)據(jù)類型定義:</p><p> typedef struct DuLNode
5、</p><p><b> {</b></p><p><b> int data;</b></p><p> struct DuLNode *prior;</p><p> struct DuLNode *next;</p><p> }DuLNode,*DuLi
6、nkList; //定義雙向循環(huán)鏈表 </p><p><b> 基本操作</b></p><p> int InitList_Dul(DuLinkList &L) //建立一個只含頭結(jié)點(diǎn)的空雙向循環(huán)鏈表</p><p> int CreateList_DuL(DuLinkList &L,int n)
7、 //建立一個帶頭結(jié)點(diǎn)的含n個元素的雙向循環(huán)鏈表L</p><p> int ListDelete_DuL(DuLinkList &L,DuLinkList x) //刪除指針x指向的結(jié)點(diǎn)</p><p><b> 3.設(shè)計思路</b></p><p> 首先建立一個雙向循環(huán)鏈表作為存儲結(jié)構(gòu),每個結(jié)點(diǎn)的數(shù)據(jù)域存儲每個人的編號,
8、然后根據(jù)給定的m值對整個鏈表進(jìn)行遍歷,找到所要找的結(jié)點(diǎn)后,輸出該結(jié)點(diǎn)的數(shù)據(jù)域的值,并在雙向循環(huán)鏈表中刪除該結(jié)點(diǎn),重復(fù)這樣的操作,一直到所有的人都出列,依次輸出的數(shù)列即為所求的Josephus排列。</p><p><b> 4.詳細(xì)設(shè)計</b></p><p> typedef struct DuLNode</p><p><b>
9、; {</b></p><p><b> int data;</b></p><p> struct DuLNode *prior;</p><p> struct DuLNode *next;</p><p> }DuLNode,*DuLinkList; //定義
10、雙向循環(huán)鏈表</p><p> int InitList_Dul(DuLinkList &L) //建立一個只含頭結(jié)點(diǎn)的空雙向循環(huán)鏈表</p><p><b> {</b></p><p> L=(DuLinkList) malloc(sizeof(DuLNode));</p><p> if
11、(!L) return ERROR;</p><p> L->data=0;</p><p> L->next=L;</p><p> L->prior=L;</p><p> return OK;</p><p><b> }</b></p><
12、;p> int CreateList_DuL(DuLinkList &L,int n) //建立一個帶頭結(jié)點(diǎn)的含n個元素的雙向循環(huán)鏈表L</p><p><b> {</b></p><p> DuLinkList p,q;</p><p><b> int i;</b></p&g
13、t;<p><b> q=L;</b></p><p> for(i=0;i<n;i++)</p><p><b> {</b></p><p> p=(DuLinkList)malloc(sizeof(DuLNode));</p><p> p->data=i+
14、1; //m值的自動獲取</p><p> p->next=q->next;</p><p> q->next=p;</p><p> p->prior=q;</p><p> L->prior=p;</p><p><b> q
15、=p;</b></p><p><b> }</b></p><p> return OK;</p><p><b> }</b></p><p> int ListDelete_DuL(DuLinkList &L,DuLinkList x) //刪除指針x指向的
16、結(jié)點(diǎn)</p><p><b> {</b></p><p> x->prior->next=x->next;</p><p> x->next->prior=x->prior;</p><p><b> free(x);</b></p>&l
17、t;p><b> return 0;</b></p><p><b> }</b></p><p> int main()</p><p><b> {</b></p><p><b> int n,m;</b></p>&l
18、t;p><b> int i=1;</b></p><p><b> cin>>n;</b></p><p> DuLinkList S;</p><p> InitList_Dul(S);</p><p> CreateList_DuL(S,n);</p>
19、<p><b> cin>>m;</b></p><p> DuLinkList a=S->next;//a指向第一個結(jié)點(diǎn)(不是頭結(jié)點(diǎn))</p><p> if(m%2==1) //奇數(shù)次順時針轉(zhuǎn)</p><p><b> {</b></p><p>
20、while(!(S->next==S->prior)) //當(dāng)剩下最后一個人時(此時還有頭結(jié)點(diǎn))時退出循環(huán)</p><p><b> {</b></p><p><b> if(i==m)</b></p><p><b> {</b></p><p>
21、DuLinkList p;</p><p> if(a->data==0)</p><p> a=a->next;//跳過頭結(jié)點(diǎn)</p><p><b> p=a;</b></p><p> a=a->next;</p><p> cout<<p->d
22、ata<<" ";</p><p> ListDelete_DuL(S,p); //刪除節(jié)點(diǎn)p</p><p><b> i=1;</b></p><p><b> }</b></p><p><b> else</b></p>
23、;<p><b> {</b></p><p> if(a->data==0)</p><p> a=a->next;//跳過頭結(jié)點(diǎn)</p><p> a=a->next;</p><p><b> i++;</b></p><p>
24、<b> }</b></p><p><b> }</b></p><p> cout<<S->next->data<<endl; //輸出最后一個出列人的的編號</p><p> free(S->next);</p><p> free(S);
25、 //釋放除頭結(jié)點(diǎn)和最后一個結(jié)點(diǎn)</p><p><b> }</b></p><p> else //偶數(shù)次逆時針轉(zhuǎn)</p><p><b> {</b></p><p> while(!(S->next==S->prior)) //當(dāng)剩下最后一個人時(此時還有頭結(jié)
26、點(diǎn))時退出循環(huán)</p><p><b> {</b></p><p><b> if(i==m)</b></p><p><b> {</b></p><p> DuLinkList p;</p><p> if(a->data==0)&
27、lt;/p><p> a=a->prior; //跳過頭結(jié)點(diǎn)</p><p><b> p=a;</b></p><p> a=a->prior;</p><p> cout<<p->data<<" ";</p><p> L
28、istDelete_DuL(S,p); //刪除節(jié)點(diǎn)p</p><p><b> i=1;</b></p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p>
29、<p> if(a->data==0)</p><p> a=a->prior; //跳過頭結(jié)點(diǎn)</p><p> a=a->prior;</p><p><b> i++;</b></p><p><b> }</b></p><p&g
30、t;<b> }</b></p><p> cout<<S->next->data<<endl; //輸出最后一個出列人的的編號</p><p> free(S->next);</p><p> free(S); //釋放除頭結(jié)點(diǎn)和最后一個結(jié)點(diǎn)</p><p>&
31、lt;b> }</b></p><p><b> return 0;</b></p><p><b> }</b></p><p><b> 5.調(diào)試分析</b></p><p><b> 1. 遇到的問題:</b></p
32、><p> (1)開始對雙向循環(huán)鏈表的刪除操作的指針改變順序出現(xiàn)了問題,導(dǎo)致刪除結(jié)點(diǎn)時出現(xiàn)了錯誤;</p><p> ?。?)雙向循環(huán)鏈表中帶有頭結(jié)點(diǎn),而頭結(jié)點(diǎn)的數(shù)據(jù)域是空的(該程序中設(shè)為0),因此在對雙向循環(huán)鏈表進(jìn)行遍歷和刪除操作時,必須判斷該結(jié)點(diǎn)是否是頭結(jié)點(diǎn),如果是,必須跳過該結(jié)點(diǎn);</p><p><b> 2.收獲:</b></p
33、><p> ?。?)通過對雙向循環(huán)鏈表的建立、遍歷、刪除等操作的實(shí)現(xiàn),對指針和鏈表了解得更加透徹,掌握得更加牢固;</p><p> ?。?)對頭結(jié)點(diǎn)問題的特殊處理,使自己解決問題的能力有了提升。</p><p><b> 6.測試結(jié)果</b></p><p> 說明:若m是奇數(shù),順時針遍歷雙向循環(huán)鏈表;若m是偶數(shù),逆時
34、針遍歷雙向循環(huán)鏈表。</p><p><b> 附錄:程序源代碼</b></p><p> /*****************************************************************************</p><p> 約瑟夫環(huán)問題求解 </p><p>
35、 東北大學(xué) 計算機(jī)科學(xué)與技術(shù)</p><p> *****************************************************************************/</p><p> #include<iostream></p><p> #include<conio.h></p>
36、<p> #include<cstdlib></p><p> using namespace std;</p><p> # define OK 1</p><p> # define ERROR 0</p><p> typedef struct DuLNode</p><p>&
37、lt;b> {</b></p><p><b> int data;</b></p><p> struct DuLNode *prior;</p><p> struct DuLNode *next;</p><p> }DuLNode,*DuLinkList;
38、 //定義雙向循環(huán)鏈表</p><p> int InitList_Dul(DuLinkList &L) //建立一個只含頭結(jié)點(diǎn)的空雙向循環(huán)鏈表</p><p><b> {</b></p><p> L=(DuLinkList) malloc(sizeof(DuLNode));</p><p&
39、gt; if(!L) return ERROR;</p><p> L->data=0;</p><p> L->next=L;</p><p> L->prior=L;</p><p> return OK;</p><p><b> }</b></p&g
40、t;<p> int CreateList_DuL(DuLinkList &L,int n) //建立一個帶頭結(jié)點(diǎn)的含n個元素的雙向循環(huán)鏈表L</p><p><b> {</b></p><p> DuLinkList p,q;</p><p><b> int i;</b><
41、/p><p><b> q=L;</b></p><p> for(i=0;i<n;i++)</p><p><b> {</b></p><p> p=(DuLinkList)malloc(sizeof(DuLNode));</p><p> p->dat
42、a=i+1; //m值的自動獲取</p><p> p->next=q->next;</p><p> q->next=p;</p><p> p->prior=q;</p><p> L->prior=p;</p><p><b>
43、; q=p;</b></p><p><b> }</b></p><p> return OK;</p><p><b> }</b></p><p> int ListDelete_DuL(DuLinkList &L,DuLinkList x) //刪除指針x指
44、向的結(jié)點(diǎn)</p><p><b> {</b></p><p> x->prior->next=x->next;</p><p> x->next->prior=x->prior;</p><p><b> free(x);</b></p>
45、<p><b> return 0;</b></p><p><b> }</b></p><p> int main()</p><p><b> {</b></p><p> while(1){ //主程序循環(huán)執(zhí)行</p><p&
46、gt;<b> int n,m;</b></p><p><b> int i=1;</b></p><p> cout<<"請輸入競賽者人數(shù)n:"<<endl;</p><p><b> cin>>n;</b></p>&
47、lt;p> DuLinkList S;</p><p> InitList_Dul(S);</p><p> CreateList_DuL(S,n);</p><p> cout<<"請輸入正整數(shù)m:"<<endl;</p><p><b> cin>>m;&l
48、t;/b></p><p> cout<<"("<<n<<","<<m<<")"<<"Josephus排列(奇數(shù)次順時針輪轉(zhuǎn),偶數(shù)次逆時針輪轉(zhuǎn))為:"<<endl;</p><p> DuLinkList a=S-&g
49、t;next;//a指向第一個結(jié)點(diǎn)(不是頭結(jié)點(diǎn))</p><p> if(m%2==1) //奇數(shù)次順時針轉(zhuǎn)</p><p><b> {</b></p><p> while(!(S->next==S->prior)) //當(dāng)剩下最后一個人時(此時還有頭結(jié)點(diǎn))時退出循環(huán)</p><p>&l
50、t;b> {</b></p><p><b> if(i==m)</b></p><p><b> {</b></p><p> DuLinkList p;</p><p> if(a->data==0)</p><p> a=a->
51、next;//跳過頭結(jié)點(diǎn)</p><p><b> p=a;</b></p><p> a=a->next;</p><p> cout<<p->data<<" ";</p><p> ListDelete_DuL(S,p); //刪除節(jié)點(diǎn)p</p&g
52、t;<p><b> i=1;</b></p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> if(a->data==0)</p>
53、<p> a=a->next;//跳過頭結(jié)點(diǎn)</p><p> a=a->next;</p><p><b> i++;</b></p><p><b> }</b></p><p><b> }</b></p><p&g
54、t; cout<<S->next->data<<endl;//輸出最后一個出列人的的編號</p><p> free(S->next);</p><p> free(S);//釋放除頭結(jié)點(diǎn)和最后一個結(jié)點(diǎn)</p><p><b> }</b></p><p> else
55、 //偶數(shù)次逆時針轉(zhuǎn)</p><p><b> {</b></p><p> while(!(S->next==S->prior))//當(dāng)剩下最后一個人時(此時還有頭結(jié)點(diǎn))時退出循環(huán)</p><p><b> {</b></p><p><b> if(i==m)&
56、lt;/b></p><p><b> {</b></p><p> DuLinkList p;</p><p> if(a->data==0)</p><p> a=a->prior;//跳過頭結(jié)點(diǎn)</p><p><b> p=a;</b>&l
57、t;/p><p> a=a->prior;</p><p> cout<<p->data<<" ";</p><p> ListDelete_DuL(S,p); //刪除節(jié)點(diǎn)p</p><p><b> i=1;</b></p><p>
58、<b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> if(a->data==0)</p><p> a=a->prior;//跳過頭結(jié)點(diǎn)</p><p> a=
59、a->prior;</p><p><b> i++;</b></p><p><b> }</b></p><p><b> }</b></p><p> cout<<S->next->data<<endl;//輸出最后一個出
60、列人的的編號</p><p> free(S->next);</p><p> free(S);//釋放除頭結(jié)點(diǎn)和最后一個結(jié)點(diǎn)</p><p><b> }</b></p><p> } //while(1)</p><p><b> return 0;</b>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 單向循環(huán)鏈表實(shí)現(xiàn)約瑟夫環(huán)
- c語言單向循環(huán)鏈表實(shí)現(xiàn)實(shí)現(xiàn)約瑟夫環(huán)
- 實(shí)驗(yàn)四 雙向鏈表
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--雙向循環(huán)鏈表的實(shí)現(xiàn)
- 用順序表解決約瑟夫環(huán)問題
- 約瑟夫問題的代碼(鏈表的運(yùn)用)
- 單鏈表、雙鏈表、循環(huán)鏈表和靜態(tài)鏈表的習(xí)題
- c語言的雙鏈表與循環(huán)鏈表
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---雙向鏈表
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告--雙向循環(huán)鏈表的創(chuàng)建及相關(guān)操作的實(shí)現(xiàn)
- 約瑟夫環(huán)-課程設(shè)計
- 求解約束Hamilton系統(tǒng)的指數(shù)擬合方法.pdf
- 求解約束優(yōu)化問題的增廣拉格朗日函數(shù)法.pdf
- 約瑟夫環(huán)問題課程設(shè)計
- 約瑟夫環(huán)課程設(shè)計報告
- 約瑟夫環(huán)課程設(shè)計報告
- 鐘曉鴻單循環(huán)鏈表基本操作
- 數(shù)據(jù)結(jié)構(gòu)約瑟夫環(huán)問題
- 求解約束優(yōu)化問題的粒子群算法研究.pdf
- 改進(jìn)的進(jìn)化算法用于求解約束優(yōu)化問題.pdf
評論
0/150
提交評論