链表-约瑟夫环
假设有n个死刑犯,将犯人拍成一圈,每个人都有个自己的编号,选择一个人作为起点,然后顺时针从1~k整数数,数到k的人退出,被处决的人的编号为下一个k,然后把这个人提出来重新算,知道最后只剩下一个人活着
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<time.h> 5 #define DEAD_MAN_NUM 10 //死刑犯的个数假设有10个死刑犯 6 typedef struct node 7 { 8 int num; 9 struct node* next; 10 }NODE; 11 void initHead(NODE** p) //分配头结点 12 { 13 NODE* temp = (NODE*)malloc(sizeof(NODE)); 14 *p = temp; 15 } 16 NODE* initDead(NODE* head)//初始化死刑犯并串联起来 17 { 18 NODE* temp, * move; 19 //通过随机数来生成死刑犯的编号一百以内 20 //申请第一个节点,然后用头指针来指向第一个节点 21 move = head; 22 for (int i = 0; i < DEAD_MAN_NUM; i++) 23 { 24 temp = (NODE*)malloc(sizeof(NODE)); 25 temp->next = NULL; 26 temp->num = rand() % 100; 27 move->next = temp; 28 move = temp; 29 } 30 move->next = head;//建立一个循环链表 31 return head; 32 } 33 int kill_Dead(NODE* head) 34 { 35 int Dead_Num; 36 NODE* temp = head; 37 NODE* release; 38 printf("请输入第一次数为多少:"); 39 scanf("%d", &Dead_Num); 40 while (1) 41 { 42 if (head->next->next == head)//如果头结点的下下一个位置是头结点说明只剩一个囚犯了 43 { 44 return head->next->num; 45 } 46 for(int i=0;i<Dead_Num;i++)//通过第一次输入的移动的次数和杀死的囚犯的编号来移动,移动到要删除的节点的前一个位置 47 { 48 if (temp->next == head) 49 { 50 //如果要移动的下一个位置是头结点的位置就要跳过头结点 51 temp = temp->next->next; 52 } 53 temp = temp->next; 54 } 55 if (temp->next == head)//如果移动到的是头结点前面的一个节点就再往后移动一个 56 { 57 temp = temp->next; 58 } 59 //开始杀人,也就是断开链表 60 Dead_Num = temp->next->num; 61 release = temp->next; 62 temp->next = temp->next->next; 63 free(release); 64 release = NULL; 65 } 66 } 67 void test(NODE* head) 68 { 69 NODE* temp = head->next; 70 while (temp != head) 71 { 72 printf("%d\n", temp->num); 73 temp = temp->next; 74 } 75 } 76 int main() 77 { 78 srand(rand()); 79 NODE* head; 80 initHead(&head); 81 head =initDead(head); 82 //test(head); 83 int Life_Man_Num; 84 Life_Man_Num = kill_Dead(head); 85 printf("最后留下来的人的编号是%d",Life_Man_Num); 86 return 0; 87 }