據說著名猶太歷史學家 josephus有過以下的故事:在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了乙個自殺方式,41個人排成乙個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下乙個重新報數,直到所有人都自殺身亡為止。然而josephus 和他的朋友並不想遵從。首先從乙個人開始,越過k-2個人(因為第乙個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下乙個人留下,這個人就可以繼續活著。問題是,給定了和,一開始要站在什麼地方才能避免被處決?josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。
建立標頭檔案儲存函式 circlelist.h
#ifndef _circlelist_h_h
#define _circlelist_h_h
typedef void circlelist;
typedef struct _tag_circlelistnode
circlelistnode;
circlelist *circlelist_create();
void circlelist_destroy(circlelist* list);
void circlelist_clear(circlelist* list);
int circlelist_length(circlelist* list);
int circlelist_insert(circlelist* list, circlelistnode* node, int pos);
circlelistnode* circlelist_get(circlelist* list,int pos);
circlelistnode* circlelist_delete(circlelist* list, int pos);
circlelistnode* circlelist_deletenode(circlelist* list, circlelistnode* node);
circlelistnode* circlelist_reset(circlelist* list);
circlelistnode* circlelist_current(circlelist* list);
circlelistnode* circlelist_next(circlelist* list);
#endif // !_circlelist_h_h
完成函式實現 circlelist.c
#define _crt_secure_no_warnings
#include #include #include #include "circlelist.h"
typedef struct _tag_circlelist
tcirclelist;
circlelist *circlelist_create()
ret->length = 0;
ret->header.next = null;
ret->slider = null;
return ret;
}void circlelist_destroy(circlelist* list)
free(list);
}void circlelist_clear(circlelist* list)
slist->length = 0;
slist->header.next = null;
slist->slider = null;
}int circlelist_length(circlelist* list)
ret = slist->length;
return ret;
}int circlelist_insert(circlelist* list, circlelistnode* node, int pos)
//if( ret )
//current->next 0號結點的位址
node->next = current->next; //1
current->next = node; // 2
//若第一次 插入結點
if (slist->length == 0)
slist->length++;
//若頭插法 current任然指向頭部
//原因是 ,跳 0 步 沒有跳走
if (current == (circlelistnode*)slist)
}return ret;
}circlelistnode* circlelist_get(circlelist* list, int pos)
ret = current->next;
} return ret;
}circlelistnode* circlelist_delete(circlelist* list, int pos)
//若刪除第乙個元素(頭結點)
if (current == (circlelistnode*)slist)
//求要刪除的元素
ret = current->next;
current->next = ret->next;
slist->length--;
//判斷鍊錶是否為空
if (last != null)
//若刪除的元素為游標所指的元素
if (slist->slider == ret)
//若刪除元素後,鍊錶長度為 0
if (slist->length == 0)
}return ret;
}//add
circlelistnode* circlelist_deletenode(circlelist* list, circlelistnode* node)
current = current->next;
} //如果ret找到 根據i去刪除
if (ret != null)
}return ret;
}circlelistnode* circlelist_reset(circlelist* list)
return ret;
}circlelistnode* circlelist_current(circlelist* list)
return ret;
}//把當前位置返回,並且游標下移
circlelistnode* circlelist_next(circlelist* list)
return ret;
}
約瑟夫 問題的呼叫josephus.c
#define _crt_secure_no_warnings
#include #include #include #include "circlelist.h"
struct value
;void main()
printf("\n");
//重置游標
circlelist_reset(list);
while (circlelist_length(list)>0)
pv = (struct value*)circlelist_current(list);
printf("%d\n", pv->v);
circlelist_deletenode(list, (circlelistnode*)pv);
//不通過位置刪除元素 通過 值 刪除元素 }
//重置游標
circlelist_destroy(list);
/*while (circlelist_length(list) > 0)
}*/printf("hello...\n");
system("pause");
}
迴圈鍊錶解決約瑟夫迴圈問題
最近開始複習資料結構,今天手寫了乙個約瑟夫迴圈問題。首尾相連的鍊錶 head last tail tail next head 建立迴圈鍊錶和建立普通鍊錶方法差不多,只需要首尾相連即可 已知 n 個人 以編號1,2,3,n分別表示 圍坐在一張圓桌周圍,從編號為 k 的人開始順時針報數,數到 m 的那...
迴圈鍊錶解決約瑟夫環問題
題目要求的約瑟夫環操作 編號是1,2,n的n個人按照順時針方向圍坐一圈,每個人只有乙個密碼 正整數 一開始任選乙個正整數作為報數上限值m,從第乙個仍開始順時針方向自1開始順序報數,報到m時停止報數。報m的人出列,將他的密碼作為新的m值,從他在順時針方向的下乙個人開始重新從1報數,如此下去,直到所有人...
迴圈鍊錶解決約瑟夫環問題
問題描述 假設有n個小孩按照序號1,2,n圍坐成一圈,從第乙個小孩開始報數,每次報到n的人退出,接著從下乙個人重新開始從1開始報數,下一次再報到n的人退出,求最後乙個留下的人 小孩的個數n,和報數的n由鍵盤輸入 輸出留下人的序號 乙個迴圈鍊錶都寫得除出了很多問題,改了半天才出來 include in...