1. 程式人生 > >約瑟夫環演算法詳解

約瑟夫環演算法詳解

約瑟夫環指的是,n個人按編號順序圍成一個環,設定一個數字m,其中m<n(一般m取0-9之間的數);並從環中的第一個人開始,按順時針數數,每數了m個位置,排在m號的位置上的人出列,然後從出列的位置的下一個位置上的人開始數,一直到環中剩下最後一個人為止。

演算法步驟:

(1)確定儲存結構:由於是一個環,所以建立一個迴圈連結串列

(2)設定指標個數:設定一個頭指標*front永遠指向第一個結點(按數字順序的話是指向環中最小的那個節點也可又從0開始數),再設定一個尾指標*prior用於指向報數的人的位置,每報一次數,尾指標指向下一個節點,數到m號時,則刪除該節點,並將尾指標指向下一個節點,一直迴圈下去。

定義節點型別:

typedef struct Node{    int data;struct Node *next;    struct Node *front;
         struct Node *prior;}Node,*LinkList;

  (3)向連結串列插入n個人(採用尾插法)

LinkList Create_cirlce(){LinkList L,r,p;L = (Node *)malloc (sizeof(Node));  //初始化連結串列 L->next = L;r = L;                              //r始終指向最後一個結點int n;while(scanf
("%d",&n) != EOF){p = (Node *)malloc(sizeof(Node));p->data = n;p->next = r->next;r->next = p;r = p;}r->next = L;return L; }

(4)根據指標判斷連結串列是否已出列到最後一個:判斷*prior->next!=L

(5)利用迴圈遍歷出出列的人:此時需利用兩個迴圈,外迴圈代表遍歷到最後一個所需要的迴圈次數,內迴圈代表遍歷出列的人

    void Josephus(int n,int m){

          for(int i=0;i<n-1;i++){

                for(int j=0;i<m-1;j++){

                        Next();//遍歷出出列的人

                        cout<<"出列的人是:"<<current;//顯示出當前出列的人的位置

                        ListDelete();//刪除節點

        }

                    }

}