1. 程式人生 > >用循環鏈表解決約瑟夫環問題

用循環鏈表解決約瑟夫環問題

循環 解決 使用 end head als list output 循環條件

約瑟夫環是一個數學的應用問題:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重復下去,直到圓桌周圍的人全部出列。

下面我們用循環列表模擬這個過程:

 1 //節點定義與單鏈表相同,在此省略
 2 //use cyclical linked list to solve josephus problem
 3 template <typename Type> class LinkedList {
 4 private:
 5     Node<Type> *head;
6 public: 7 LinkedList() { 8 head = NULL; 9 } 10 11 ~LinkedList() { 12 if(head==NULL){ 13 return; 14 } 15 //head表示尾節點,head->next表示頭節點 16 Node<Type> *current_node = head->next; 17 //拆成單鏈表 18 head->next=NULL;
19 while (current_node != NULL) { 20 Node<Type> *delete_node = current_node; 21 current_node = current_node->next; 22 delete delete_node; 23 } 24 } 25 26 bool insert(Node<Type> *node, int index) { 27 if (head == NULL) {
28 if (index != 0) { 29 return false; 30 } 31 head = node; 32 //只有一個節點時,next指向自己 33 head->next=head; 34 return true; 35 } 36 if (index == 0) { 37 node->next = head->next; 38 head->next = node; 39 return true; 40 } 41 Node<Type> *current_node = head->next; 42 int count = 0; 43 while (current_node != head && count < index - 1) { 44 current_node = current_node->next; 45 count++; 46 } 47 if (count == index - 1) { 48 node->next = current_node->next; 49 current_node->next = node; 50 //如果加到鏈表末尾,需更新尾節點 51 if(node==head->next){ 52 head=node; 53 } 54 return true; 55 } 56 return false; 57 } 58 59 //刪除數到m的元素並按被刪順序輸出,最後被輸出的即為留到最後的 60 void output_josephus(int m){ 61 Node<Type> *current_node=head; 62 //之後不再使用head指針,所以在這裏把它指空,防止最後成為野指針, 63 //因為尾節點可能會被刪掉 64 head=NULL; 65 //循環條件:剩下不止一個元素 66 while(current_node->next!=current_node){ 67 //從尾節點開始數,數到m時恰好是從頭數第m-1個元素 68 for(int i=1;i<m;i++){ 69 current_node=current_node->next; 70 } 71 cout<<current_node->next->data<<" "; 72 Node<Type> *delete_node=current_node->next; 73 current_node->next=current_node->next->next; 74 delete delete_node; 75 } 76 //最後剩余的一個節點 77 cout<<current_node->data<<endl; 78 delete current_node; 79 } 80 };

用循環鏈表解決約瑟夫環問題