約瑟夫環演算法詳解
阿新 • • 發佈:2019-02-16
約瑟夫環指的是,n個人按編號順序圍成一個環,設定一個數字m,其中m<n(一般m取0-9之間的數);並從環中的第一個人開始,按順時針數數,每數了m個位置,排在m號的位置上的人出列,然後從出列的位置的下一個位置上的人開始數,一直到環中剩下最後一個人為止。
演算法步驟:
(1)確定儲存結構:由於是一個環,所以建立一個迴圈連結串列
(2)設定指標個數:設定一個頭指標*front永遠指向第一個結點(按數字順序的話是指向環中最小的那個節點也可又從0開始數),再設定一個尾指標*prior用於指向報數的人的位置,每報一次數,尾指標指向下一個節點,數到m號時,則刪除該節點,並將尾指標指向下一個節點,一直迴圈下去。
定義節點型別:
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();//刪除節點
}
}
}