约瑟夫环的简单实现(C++链表)
约瑟夫环(Joseph Circle)
编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。现在给定一个随机数m>0,从编号为1的人开始,按顺时针方向1开始顺序报数,报到m时暂停。报m的人出圈,同时留下他的密码作为新的m值,从他在顺时针方向上的下一个人开始,重新从1开始报数,如此下去,直至所有的人全部出列为止。


对应的密码为顺序为:4 8 9 15 22 1 3
1 #include <iostream> 2 using namespace std; 3 4 typedef struct Node 5 { 6 int e; 7 struct Node* next; 8 }Node, *Linklist; 9 //Linklist 一个节点的指针 10 void initlist(Linklist &head) 11 { 12 int n; 13 Linklist head_ptr,tail_ptr,temp; 14 head = (Linklist)malloc(sizeof(Node)); 15 head->next = nullptr; 16 head_ptr = head; 17 tail_ptr = head; 18 cout << "输入需要节点个数:"; 19 cin >> n; 20 for (int i = 0; i < n; i++) 21 { 22 temp= (Linklist)malloc(sizeof(Node)); 23 temp->next = nullptr; 24 tail_ptr->next= temp ; 25 cout << "第" << i + 1 << "个节点:"; 26 cin >> temp->e; 27 tail_ptr=tail_ptr->next ; 28 } 29 30 } 31 32 void show(Linklist list) 33 { 34 Linklist p = list; 35 p = p->next; 36 while (p != nullptr) 37 { 38 cout << p->e << endl; 39 p = p->next; 40 } 41 } 42 43 void remove(Linklist list) 44 { 45 int n; 46 printf("输入需要删除的节点:"); 47 cin >> n; 48 Linklist p=list; 49 while (p->next->e != n) 50 { 51 p = p->next; 52 } 53 Linklist t = p->next; 54 p->next = p->next->next; 55 free(t); 56 printf("删除结果:\n"); 57 show(list); 58 59 } 60 61 void insert(Linklist& list) { 62 int n,i=0; 63 Linklist t = (Linklist)malloc(sizeof(Node)); 64 Linklist p = list; 65 printf("输入插入的节点元素:"); 66 cin >> t->e ; 67 printf("输入插入的位置:"); 68 cin >> n; 69 p = p->next; 70 while (1) 71 { 72 if (i == n - 1) 73 { 74 break; 75 } 76 p = p->next; 77 i++; 78 } 79 t->next = p->next; 80 p->next = t; 81 printf("插入结果:\n"); 82 show(list); 83 84 } 85 86 void JosehpInit(Linklist list) //用来构建一个循环链表,假设每个节点的e就是该节点的密码,头节点也存放一个密码 87 { 88 Linklist p; //list就是该链表的头节点的地址 89 list->e = 3; //假设头节点作为一号节点,约瑟夫环开始的第1个节点,并将它的密码设置成3,循环列表的输入从第二号节点开始,一号是头节点,写在程序中 90 p = list; 91 while (p->next != nullptr) { p = p->next; } 92 p->next = list;//list为头节点,将头节点和尾结点连起来 93 94 } 95 96 void JosehpImpl(Linklist list) 97 { 98 Linklist p = list,t=nullptr; 99 int m=4; //假设初始的密码是5,这里要定义成4(密码-1) 100 while (p->next!=p) 101 { 102 p = p->next; 103 m--; 104 if (m == 1)//此时p指针的下一个人就是将要出去的人 105 { 106 t = p->next; //一定要注意先后顺序!!!在这卡了半天看不出毛病 107 108 m = p->next->e; //先将key替换为将要出去的人的密码 109 cout << p->next->e << endl; 110 p->next = p->next->next; 111 free(t); 112 } 113 114 } 115 cout << p->e; 116 } 117 118 int main() 119 { 120 Linklist list; 121 initlist(list); 122 JosehpInit(list); 123 JosehpImpl(list); 124 return 0; 125 }

浙公网安备 33010602011771号