您的位置:首页 > 其它

【学习总结】循环链表模拟约瑟夫问题和循环链表的初始化、建立、删除(按值与按位置)

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐