用循环链表解决约瑟夫环问题
Posted NoviScl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用循环链表解决约瑟夫环问题相关的知识,希望对你有一定的参考价值。
约瑟夫环是一个数学的应用问题:已知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 };
以上是关于用循环链表解决约瑟夫环问题的主要内容,如果未能解决你的问题,请参考以下文章