17.环形链表,以及用环形链表解决约瑟夫问题
Posted 喵小喵~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17.环形链表,以及用环形链表解决约瑟夫问题相关的知识,希望对你有一定的参考价值。
- 运行结果
-
- 链表定义
typedef struct LinkNode { int data; struct LinkNode *pNext; }node,*PNODE;
- 环形链表尾部添加
1 //尾部添加 2 PNODE addback(PNODE phead, int data) 3 { 4 //分配空间 5 PNODE pnew = (PNODE)malloc(sizeof(node)); 6 pnew->data = data; 7 if (phead == NULL) 8 { 9 phead = pnew; 10 pnew->pNext = phead; 11 } 12 else 13 { 14 //循环到尾部 15 PNODE p = phead; 16 while (p->pNext != phead) 17 { 18 p = p->pNext; 19 } 20 p->pNext = pnew; 21 //头尾相连 22 pnew->pNext = phead; 23 } 24 25 return phead; 26 }
- 环形链表头部添加
1 //头部添加 2 PNODE addfront(PNODE phead, int data) 3 { 4 //分配空间 5 PNODE pnew = (PNODE)malloc(sizeof(node)); 6 pnew->data = data; 7 if (phead == NULL) 8 { 9 phead = pnew; 10 pnew->pNext = phead; 11 } 12 else 13 { 14 PNODE p = phead; 15 while (p->pNext != phead) 16 { 17 p = p->pNext; 18 } 19 //新的结点插在头结点之前 20 pnew->pNext = phead; 21 //尾结点指向头结点 22 p->pNext = pnew; 23 //新的结点赋值给头结点 24 phead = pnew; 25 } 26 return phead; 27 }
- 显示数据
1 void showall(PNODE phead) 2 { 3 if (phead == NULL) 4 { 5 return; 6 } 7 else if (phead->pNext == phead) 8 { 9 printf("%d,%p,%p\\n", phead->data, phead, phead->pNext); 10 } 11 else 12 { 13 PNODE p = phead; 14 while (p->pNext != phead) 15 { 16 printf("%d,%p,%p\\n", p->data, p, p->pNext); 17 p = p->pNext; 18 } 19 printf("%d,%p,%p\\n", p->data, p, p->pNext); 20 } 21 }
- 查找第一个指定元素
PNODE findfirst(PNODE phead, int data) { if (phead == NULL) { return NULL; } else if (phead->pNext == phead) { if (phead->data == data) { return phead; } } else { PNODE p = phead; while (p->pNext != phead) { if (p->data == data) { return p; } p = p->pNext; } if (p->data == data) { return p; } } return NULL; }
- 删除指定结点 判断有几个结点1.1个 2.大于一个(大于一个要判断是否是头结点)
1 PNODE deletefirst(PNODE phead, int data) 2 { 3 //p2用于保存p1的前一个位置 4 PNODE p1 = NULL; 5 PNODE p2 = NULL; 6 p1 = phead; 7 8 //如果只有 一个结点 9 if (p1->pNext == phead) 10 { 11 if (p1->data == data) 12 { 13 return NULL; 14 } 15 else 16 { 17 return phead; 18 } 19 } 20 //如果结点数大于一个 21 else 22 { 23 //先判断头结点,如果头结点是则要删除头结点 24 if (phead->data == data) 25 { 26 //遍历到尾部 27 while (p1->pNext != phead) 28 { 29 p1 = p1->pNext; 30 } 31 //尾部的后一个结点是头结点的后一个结点 32 p1->pNext = phead->pNext; 33 //释放头结点 34 free(phead); 35 //把尾接电脑的后一个赋给phead 36 phead = p1->pNext; 37 } 38 else 39 { 40 //如果头结点不是要删除的结点,则从后一个开始遍历,p2保存p1移动前的位置 41 p2 = p1; 42 p1 = phead->pNext; 43 //遍历到头结点 44 while (p1 != phead) 45 { 46 if (p1->data == data) 47 { 48 break; 49 } 50 else 51 { 52 p2 = p1; 53 p1 = p1->pNext; 54 } 55 } 56 //判断是否找到结点 57 if (p1 != phead) 58 { 59 p2->pNext = p1->pNext; 60 free(p1); 61 } 62 } 63 return phead; 64 } 65 }
- 统计有多少个结点
1 int getnum(PNODE phead) 2 { 3 if (phead == NULL) 4 { 5 return 0; 6 } 7 else 8 { 9 int num = 1; 10 PNODE p = phead; 11 while (p->pNext != phead) 12 { 13 num++; 14 p = p->pNext; 15 } 16 return num; 17 } 18 }
- 在指定元素之后插入一个数据 先判断有几个结点 1.1个 2.大于1个
1 PNODE insertfirst(PNODE phead, int finddata, int data) 2 { 3 PNODE pnew = (PNODE)malloc(sizeof(node)); 4 pnew->data = data; 5 6 if (phead == NULL) 7 { 8 return NULL; 9 } 10 //如果只有一个结点 11 else if (phead->pNext == phead) 12 { 13 if (phead->data == finddata) 14 { 15 phead->pNext = pnew; 16 pnew->pNext = phead; 17 return phead; 18 } 19 } 20 else 21 { 22 PNODE p = phead; 23 while (p->pNext != phead) 24 { 25 if (p->data == finddata) 26 { 27 pnew->pNext = p->pNext; 28 p->pNext = pnew; 29 return phead; 30 } 31 p = p->pNext; 32 } 33 if (p->data == finddata) 34 { 35 p->pNext = pnew; 36 pnew->pNext = phead; 37 return phead; 38 } 39 } 40 41 }
- 完整代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct LinkNode 5 { 6 int data; 7 struct LinkNode *pNext; 8 }node,*PNODE; 9 10 //尾部添加 11 PNODE addback(PNODE phead, int data) 12 { 13 //分配空间 14 PNODE pnew = (PNODE)malloc(sizeof(node)); 15 pnew->data = data; 16 if (phead == NULL) 17 { 18 phead = pnew; 19 pnew->pNext = phead; 20 } 21 else 22 { 23 //循环到尾部 24 PNODE p = phead; 25 while (p->pNext != phead) 26 { 27 p = p->pNext; 28 } 29 p->pNext = pnew; 30 //头尾相连 31 pnew->pNext = phead; 32 } 33 34 return phead; 35 } 36 37 //头部添加 38 PNODE addfront(PNODE phead, int data) 39 { 40 //分配空间 41 PNODE pnew = (PNODE)malloc(sizeof(node)); 42 pnew->data = data; 43 if (phead == NULL) 44 { 45 phead = pnew; 46 pnew->pNext = phead; 47 } 48 else 49 { 50 PNODE p = phead; 51 while (p->pNext != phead) 52 { 53 p = p->pNext; 54 } 55 //新的结点插在头结点之前 56 pnew->pNext = phead; 57 //尾结点指向头结点 58 p->pNext = pnew; 59 //新的结点赋值给头结点 60 phead = pnew; 61 } 62 return phead; 63 } 64 65 //显示数据 66 void showall(PNODE phead) 67 { 68 if (phead == NULL) 69 { 70 return; 71 } 72 else if (phead->pNext == phead) 73 { 74 printf("%d,%p,%p\\n", phead->data, phead, phead->pNext); 75 } 76 else 77 { 78 PNODE p = phead; 79 while (p->pNext != phead) 80 { 81 printf("%d,%p,%p\\n", p->data, p, p->pNext); 82 p = p->pNext; 83 } 84 printf("%d,%p,%p\\n", p->data, p, p->pNext); 85 } 86 } 87 88 //查找第一个指定元素 89 PNODE findfirst(PNODE phead, int data) 90 { 91 if (phead == NULL) 92 { 93 return NULL; 94 } 95 else if (phead->pNext == phead) 96 { 97 if (phead->data == data) 98 { 99 return phead; 100 } 101 } 102 else 103 { 104 PNODE p = phead; 105 while (p->pNext != phead) 106 { 107 if (p->data == data) 108 { 109 return p; 110 } 111 p = p->pNext; 112 } 113 if (p->data == data) 114 { 115 return p; 116 } 117 } 118 119 return NULL; 120 } 121 122 //删除指定结点 判断有几个结点1.1个 2.大于一个(大于一个要判断是否是头结点) 123 PNODE deletefirst(PNODE phead, int data) 124 { 125 //p2用于保存p1的前一个位置 126 PNODE p1 = NULL; 127 PNODE p2 = NULL; 128 p1 = phead; 129 130 //如果只有 一个结点 131 if (p1->pNext == phead) 132 { 133 if (p1->data == data) 134 { 135 return NULL; 136 } 137 else 138 { 139 return phead; 140 } 141 } 142 //如果结点数大于一个 143 else 144 { 145 //先判断头结点,如果头结点是则要删除头结点 146 if (phead->data == data) 147 { 148 //遍历到尾部 149 while (p1->pNext != phead) 150 { 151 p1 = p1->pNext; 152 } 153 //尾部的后一个结点是头结点的后一个结点 154 p1->pNext = phead->pNext; 155 //释放头结点 156 free(phead); 157 //把尾接电脑的后一个赋给phead 158 phead = p1->pNext; 159 } 160 else 161 { 162 //如果头结点不是要删除的结点,则从后一个开始遍历,p2保存p1移动前的位置 163 p2 = p1; 164 p1 = phead->pNext; 165 //遍历到头结点 166 while (p1 != phead) 167 { 168 if (p1->data == data) 169 { 170 break; 171 } 172 else 173 { 174 p2 = p1; 175 p1 = p1->pNext; 176 } 177 } 178 //判断是否找到结点 179 if (p1 != phead) 180 { 181 p2->pNext = p1->pNext; 182 free(p1); 183 } 184 } 185 return phead; 186 } 187 } 188 189 //统计有多少个结点 190 int getnum(PNODE phead) 191 { 192 if (phead == NULL) 193 { 194 return 0; 195 } 196 else 197 { 198 int num = 1; 199 PNODE p = phead; 200 while (p->pNext != phead) 201 { 202 num++; 203 p = p->pNext; 204 } 205 return num; 206 } 207 } 208 209 //在指定元素之后插入一个数据 先判断有几个结点 1.1个 2.大于1个 210 PNODE insertfirst(PNODE phead, int finddata, int data) 211 { 212 PNODE pnew = (PNODE)malloc(sizeof(node)); 213 pnew->data = data; 214 215 if (phead == NULL) 216 { 217 return NULL; 218 } 219 //如果只有一个结点 220 else if (phead->pNext == phead) 221 { 222 if (phead->data == finddata) 223 { 224 phead->pNext = pnew; 225 pnew->pNext = phead; 226 return phead; 227 } 228 } 229 else 230 { 231 PNODE p = phead; 232 while (p->pNext != phead) 233 { 234 if (p->data == finddata) 235 { 236 pnew->pNext = p->pNext; 237 p->pNext = pnew; 238 return phead; 239 } 240 p = p->pNext; 241 } 242 if (p->data == finddata) 243 { 244 p->pNext = pnew; 245 pnew->pNext = phead; 246 return phead; 247 } 248 } 249 250 } 251 252 void main() 253 { 254 PNODE phead = NULL;//头结点 255 256 //添加 257 for (int i = 1; i <= 10; i++) 258 { 259 phead = addback(phead, i);//单向环形链表解决Josephu(约瑟夫)问题