【学习总结】循环链表模拟约瑟夫问题和循环链表的初始化、建立、删除(按值与按位置)
2017-03-25 16:52
507 查看
#include<stdio.h> #include<stdlib.h> #include<time.h> typedef struct node { int data; struct node *next; }Lnode, *Pnode; //初始化 Pnode Init_Linklist(void) { Pnode H; H = (Pnode)malloc(sizeof(Lnode)); if (H) { H->next = NULL; } return H; } //新建循环单链表 Pnode Build_Linklist(Pnode H, int length) { Pnode p, q; q = H; for (int i = 1; i <= length; i++) { p = (Pnode)malloc(sizeof(Lnode)); p->data = i; q->next = p; q = p; } q->next = H->next;//在这里Vs不能用p->next=H->next return H; } //打印循环单链表 void Print_Linklist(Pnode H) { Pnode p = H->next; while (p->next != H->next) { printf("%d ", p->data); p = p->next; } printf("%d ", p->data); } //按值查找 int Value_Find_Linklist(Pnode H, int value) { Pnode q = H->next; int i = 1; while (q->next != H->next && q->data != value) { q = q->next; i++; } if (q->next == H->next) { if (q->data == value) { return i; } else { printf("Not Find"); return 0; } } if (q->data == value) { return i; } } //按位置查找 Pnode Position_Find_Linklist(Pnode H, int position) { if (position <0) { printf("查找的位置不存在"); return NULL; } //为了修正无法删除第一个结点。 if (position == 0) { Pnode tail = H->next; while (tail->next != H->next) { tail = tail->next; } H->next = H->next->next;//为了修正头结点继续指向第二个结点。 return tail; } Pnode p = H->next; int i = 1; while (p->next != H->next && i != position) { p = p->next; i++; } if (p->next == H->next) { if (i == position) { return p; } else { return NULL; } } if (i == position) { return p; } } //按位置删除 Pnode Position_Delete_Linklist(Pnode H, int position) { Pnode pre, current; pre = Position_Find_Linklist(H, position - 1); if (pre == NULL) { printf("删除的位置不合法\n"); return H; } current = pre->next; pre->next = current->next; free(current); return H; } //按值删除 Pnode Value_Delete_Linklist(Pnode H, int value) { int currentPosition = Value_Find_Linklist(H, value); if (currentPosition == 0) { printf("删除的值不存在\n"); return H; } H = Position_Delete_Linklist(H, currentPosition); return H; } //约瑟夫问题核心代码 void Josephus_Linklist(Pnode H, int s, int m) { Pnode preDp, currentDp; //找s位置 preDp=Position_Find_Linklist(H, s-1); //找出第一个出列的人 while (preDp->next != preDp) { for (int i = 1; i < m; i++) { preDp = preDp->next; } currentDp = preDp->next; preDp->next = currentDp->next; printf("%d ",currentDp->data); free(currentDp); } printf("%d ", preDp->data); } int main(void) { Pnode H; srand(time(NULL)); H = Init_Linklist(); H = Build_Linklist(H, rand()%10+10); printf("初始化后:\n"); Print_Linklist(H); int s = rand()%10+1;//第一次报数位置。一定要小于总人数。 int m = rand()%10;//出列的数字 printf("\n出列顺序为:\n"); Josephus_Linklist( H, s,m); return 0; }
相关文章推荐
- 2016年12月21日学习总结----单向循环链表操作程序(头插,尾插,中间插入,删除,逆序)
- 2016年12月23日学习总结----双向循环链表操作程序(头插、尾插、中间插入、删除)
- 循环链表 实现对循环链表的初始化,创建,插入,删除,输出操作
- 循环链表的初始化、插入、删除、返回结点位置、遍历
- 双链表的初始化,建立,插入,查找,删除。
- 双链表的初始化,建立,插入,查找,删除
- 建立,删除循环链表中的一个元素
- 双向链表的初始化,建立,添加节点和删除节点(注意插入和删除要分三种情况)
- 单链表的初始化,建立,插入,查找,删除
- c语言实现单链表建立,插入,删除,查找,循环链表,静态链表
- 单链表的初始化,建立,插入,查找,删除
- 单向循环链表创建、遍历、插入、删除、查找(按位置,按元素值)、清空、销毁
- 双链表( 初始化,建立,插入,查找,删除 )
- 单循环链表的初始化、创建、删除、查找与遍历
- 剑指Offer学习总结-在O(1)时间删除链表结点
- 双向链表的功能实现:初始化,插入,按位置插入,按位置删除,按值删除,遍历打印等
- 初始化链表 ,插入结点,删除结点,返回结点位置 ,遍历链表 。
- 双向循环链表的建立,插入,删除(不带头结点)
- 剑指Offer学习总结-链表添加尾结点-删除结点
- 单循环链表的初始化、插入、删除、遍历、查找