约瑟夫问题
约瑟夫问题:
用循环链表模拟约瑟夫问题,把41个人自杀的顺序编号输出:
1 //n个人围圈报数,报m出列,最后剩下的是几号? 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 typedef struct node 6 { 7 int data; 8 struct node *next; 9 }node; 10 11 node *create(int n) 12 { 13 node *p = NULL, *head; 14 node *s; 15 int i = 1; 16 head = (node*)malloc(sizeof (node )); 17 p = head; 18 19 if( 0 != n ) 20 { 21 while( i <= n ) 22 { 23 s = (node *)malloc(sizeof (node)); 24 s->data = i++; // 为循环链表初始化,第一个结点为1,第二个结点为2。 25 p->next = s; 26 p = s; 27 } 28 s->next = head->next; 29 } 30 31 free(head); 32 33 return s->next ; 34 } 35 36 int main() 37 { 38 int n = 41; 39 int m = 3; 40 int i; 41 node *p = create(n); 42 node *temp; 43 44 m %= n; // m在这里是等于2 45 46 while (p != p->next ) 47 { 48 for (i = 1; i < m-1; i++) 49 { 50 p = p->next ; 51 } 52 53 printf("%d->", p->next->data ); 54 55 temp = p->next ; //删除第m个节点 56 p->next = temp->next ; 57 free(temp); 58 59 p = p->next ; 60 } 61 62 printf("%d\n", p->data ); 63 64 return 0; 65 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MAX_NODE_NUM 100 4 #define TRUE 1U 5 #define FALSE 0U 6 7 typedef struct NodeType 8 { 9 int id; 10 int cipher; 11 struct NodeType *next; 12 } NodeType; 13 14 /* 创建单向循环链表 */ 15 static void CreaList(NodeType **, const int); 16 /* 运行"约瑟夫环"问题 */ 17 static void StatGame(NodeType **, int); 18 /* 打印循环链表 */ 19 static void PrntList(const NodeType *); 20 /* 得到一个结点 */ 21 static NodeType *GetNode(const int, const int); 22 /* 测试链表是否为空, 空为TRUE,非空为FALSE */ 23 static unsigned EmptyList(const NodeType *); 24 25 int main(void) 26 { 27 int n, m; 28 NodeType *pHead = NULL; 29 while (1) 30 { 31 printf("请输入人数n(最多%d个): ", MAX_NODE_NUM); 32 scanf("%d", &n); 33 printf("和初始密码m: "); 34 scanf("%d", &m); 35 if (n > MAX_NODE_NUM) 36 { 37 printf("人数太多,请重新输入!\n"); 38 continue; 39 } 40 else 41 break; 42 } 43 CreaList(&pHead, n); 44 printf("\n------------ 循环链表原始打印 -------------\n"); 45 PrntList(pHead); 46 printf("\n-------------删除出队情况打印 -------------\n"); 47 StatGame(&pHead, m); 48 } 49 50 static void CreaList(NodeType **ppHead, const int n) 51 { 52 int i, iCipher; 53 NodeType *pNew, *pCur; 54 for (i = 1; i <= n; i++) 55 { 56 printf("输入第%d个人的密码: ", i); 57 scanf("%d", &iCipher); 58 pNew = GetNode(i, iCipher); 59 if (*ppHead == NULL) 60 { 61 *ppHead = pCur = pNew; 62 pCur->next = *ppHead; 63 } 64 else 65 { 66 pNew->next = pCur->next; 67 pCur->next = pNew; 68 pCur = pNew; 69 } 70 } 71 printf("完成单向循环链表的创建!\n"); 72 } 73 74 static void StatGame(NodeType **ppHead, int iCipher) 75 { 76 int iCounter, iFlag = 1; 77 NodeType *pPrv, *pCur, *pDel; 78 pPrv = pCur = *ppHead; 79 /* 将pPrv初始为指向尾结点,为删除作好准备 */ 80 while (pPrv->next != *ppHead) 81 pPrv = pPrv->next; 82 while (iFlag) 83 { 84 for (iCounter = 1; iCounter < iCipher; iCounter++) 85 { 86 pPrv = pCur; 87 pCur = pCur->next; 88 } 89 if (pPrv == pCur) 90 iFlag = 0; 91 pDel = pCur; /* 删除pCur指向的结点,即有人出列 */ 92 pPrv->next = pCur->next; 93 pCur = pCur->next; 94 iCipher = pDel->cipher; 95 printf("第%d个人出列, 密码: %d\n", pDel->id, pDel->cipher); 96 free(pDel); 97 } 98 *ppHead = NULL; 99 getchar(); 100 } 101 102 static void PrntList(const NodeType *pHead) 103 { 104 const NodeType *pCur = pHead; 105 if (EmptyList(pHead)) 106 return; 107 do 108 { 109 printf("第%d个人, 密码: %d\n", pCur->id, pCur->cipher); 110 pCur = pCur->next; 111 } 112 while (pCur != pHead); 113 getchar(); 114 } 115 116 static NodeType *GetNode(const int iId, const int iCipher) 117 { 118 NodeType *pNew; 119 pNew = (NodeType *)malloc(sizeof(NodeType)); 120 if(!pNew) 121 { 122 printf("Error, the memory is not enough!\n"); 123 exit(-1); 124 } 125 pNew->id = iId; 126 pNew->cipher = iCipher; 127 pNew->next = NULL; 128 return pNew; 129 } 130 131 static unsigned EmptyList(const NodeType *pHead) 132 { 133 if(!pHead) 134 { 135 printf("The list is empty!\n"); 136 return TRUE; 137 } 138 return FALSE; 139 }