用雙向循環(huán)鏈表求解約瑟夫環(huán)_第1頁
已閱讀1頁,還剩8頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論