1. 程式人生 > >線性表---單迴圈連結串列(約瑟夫環問題)

線性表---單迴圈連結串列(約瑟夫環問題)

約瑟夫環問題:

已知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.