約瑟夫環問題(動態連結串列操作)n個學生圍成一圈,每m個出隊,輸出所有出隊的序列
阿新 • • 發佈:2018-12-12
需求:掌握連結串列的簡單操作(增刪查改)詳解在備註中指出
#include <iostream> #include <stdlib.h> #include <stdio.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ struct node{ int data;//資料 node* next;//指標 }; node* creat(int array[],int n)// 建立一個長度為n的迴圈列表 { node *p,*head,*pre;// 建立現在指標,頭指標,前指標 head =new node;// 新建立一個空的頭地址 head->next=NULL;// 先進行置空 pre=head;// 將前指標置為頭結點 for(int i=0;i<n;i++)// 建立n個長度的連結串列 { p=new node; // 建立新節點 p->next=NULL;// 先進行置空 pre->next=p;// 和新建的連線 p->data=array[i];// 將新建節點賦值 pre=p;// 推進 } p->next=head;// 因為是迴圈列表將尾指標指向頭指標 return head;// 返回頭指標(頭指標data沒賦值) } void delet(node* head,int length,int m)// 將指定head頭的連結串列的第m個刪除並輸出(迴圈 ) { node *pre,*p; int count=1,sum=0;//建立計數器(p的位置)和sum pre=head;//頭結點指定head p=head->next;//p(現在節點)指向第1個元素 while(length!=0)//當連結串列中沒元素時退出 { if(p==head)//當迴圈到頭結點時因為不應該進行計數所以推進 { pre=pre->next;//將兩個節點推進 p=p->next; } if(count==m)//如果當p(現在節點)的計數等於m ,刪除該p節點 { printf("第%d個出隊:%d號學生\n",++sum,p->data);//輸出 該刪除的節點 pre->next=p->next;//直接將p前一節點的指標域賦為p的下一個節點的地址(跳過p節點) delete(p);//釋放空間 此時p的地址為空 p=pre->next;// 將p的地址賦為pre的下一個地址(始終保持p在pre前) length--;//長度減一 count=0;//重置計數器 } else//如果沒有刪除節點那麼p節點就沒有變化,此時我們推進 { pre=pre->next; p=p->next; } count++;//推進一次計數器加一,當刪除一個元素後,p直接為下一個地址,等於說p推進了一次,那麼計數器也應該加一 } } int main() { int n,m; int arr[1000]; for(int i=0;i<n;i++)//將學生編號 { arr[i]=i+1;//學生編號為1,2,3,4.... } printf("請輸入學生數目n 迴圈次數m\n1代表1號學生\n"); scanf("%d%d",&n,&m);//錄入n,m node* l=creat(arr,n);//呼叫兩個方法 delet(l,n,m); return 0; }