線性表---單迴圈連結串列(約瑟夫環問題)
阿新 • • 發佈:2019-02-13
約瑟夫環問題:
已知n個人(以編號1,2,3…n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。
程式碼:
#include <iostream>
#include <stdio.h>
#include<malloc.h>
using namespace std;
typedef struct CycleList{
int data;
struct CycleList *next;
}CLNode;
void Josephus(int n, int k, int m)
{//n為總人數,k為第一個開始報數的人,m為出列者報的數
/*---------------------------建立迴圈單鏈表--------------------------*/
CLNode *head, *p, *q;
//先建立一個只有一個節點的迴圈連結串列head,然後用迴圈逐漸往裡追加節點!!!
head = (CLNode*)malloc(sizeof(CLNode));
head->data = 1;
head->next = head;
//追加節點
p = head;
for (int i=2; i<=n;i++)
{
q = (CLNode*)malloc(sizeof(CLNode));
q->data = i;
//插入
p->next = q;
p = q;
}
p->next = head;//最後一個節點指向頭部,形成迴圈連結串列
/*---------------------------建立迴圈單鏈表--------------------------*/
/*---------------------------列印原始連結串列--------------------------*/
CLNode *pr; //(1)
pr=head; //(2)
while(pr)//!!!!
{
printf("%d ",pr->data); //(3)
pr=pr->next; //(4)
if(pr->data == head->data)//單迴圈增加
break;
}
cout<<endl;
/*---------------------------列印原始連結串列--------------------------*/
/*------------------------找到最開始報數的節點---------------------*/
CLNode *r1, *r2, *r3;
r1 = head;//注意:head節點有資料,也就是所謂的沒有頭結點
while(k--)
{//找到最開始報數的節點
r2 = r1;//r2為最開始報數的節點
r1 = r1->next;
}
//列印最開始報數的節點
cout<<r2->data<<endl;
/*------------------------找到最開始報數的節點---------------------*/
/*-----------------------------依次刪除--------------------------*/
while(n--)
{//每報到m則刪除一個節點,直至全部出列
for(int j=1; j<m; j++)
{
r3 = r2;//r3為r2的前一節點!!!
r2 = r2->next;//r2為要刪除的節點
}
r3->next = r2->next;
if(r2->next == r2)//最後一個元素
cout<<r2->data<<endl;
else
cout<<r2->data<<"->";
free(r2);
r2 = r3->next;//重置每次開始報數的節點(刪除節點的下一個)
}
/*-----------------------------依次刪除--------------------------*/
}
int main(){
Josephus(6,4,2);
return 0;
}
結果:
1 2 3 4 5 6
4
5->1->3->6->4->2
Process returned 0 (0x0) execution time : 0.070 s
Press any key to continue.