约瑟夫环双向链表,略微麻烦的一部分
#include <malloc.h>
/*该约瑟夫环使用的是循环链表*/
/*构建结构体*/
typedef struct Node{
int Num;
struct Node *next;
struct Node *pre;
}JoseNode, *PNode, *HNode;//这个结构代表一个数据域和指针域的结点
/**********初始化循环双向链表*********/
void InitList(HNode *h) //改变头指针
{
*h = (HNode)malloc(sizeof(JoseNode));
if (*h == NULL)
exit(0);
(*h)->next = *h;
(*h)->pre = *h;
}
双向链表的插入图表
/*************双向链表插入操作**********/
int JoseInsert(JoseNode *h, int pos, int x)//pos代表插入位置position,x代表插入的数,JoseNode *h是结构体约瑟夫环
{
PNode p=h,q,s;//为p赋值h,q是用于插入的结点
int i=1;//此处的i用于将p的指针向插入点靠近
while(i<pos-1)
{
++i;
p = p->next;
}
q = p->next;
s=(PNode)malloc(sizeof(JoseNode));//为插入节点赋予空间
s->Num = x;
s->next = q; //先改变向右的指针
p->next = s;
s->pre = p; //改变向左的指针
q->pre = s;
return 0;
}
双向链表删除操作图表
/**************出局函数****************/
int JoseDelete(HNode h, int M, int k)//其实就是删除结点,M是剩余人数,k代表密码,密码随报数人改变改变
{ int i;
int count=1;
PNode p=h,q;
while(M>1)
{
for(i=1;i<k-1;i++){
p = p->next;
}
q = p->next;
k = q->Num;
p->next=q->next;
q->next->pre = p;
free(q);
printf("出局的人为:%d号\n",k);
M--;
}
printf("***************获胜者为:%d号***************",p->Num);
return 1;
}
接下来是遍历函数已经主函数,这一段就很轻松了!
/*遍历*/
void TraverseList(HNode h, int M)
{
int i = 0;
PNode p = h;
printf("参与的人的密码为:\n");
while (i<M)
{
printf("%d\t", p->Num);
p = p->next;
i++;
}
printf("\n");
}
/***************************************/
int main()
{
int i;//计数器
int N;//参与的人数
int k;//每个人的密码
printf("请输入参与人数:");
scanf("%d",&N);
printf("请输入出局密码:");
scanf("%d",&k);
/**************得到头结点****************/
HNode h = ((HNode)malloc(sizeof(JoseNode)));
/***************初始化单链表************/
InitList(&h);
/******将密码插入到循环双向链表中******/
for(int i = 1;i<=N;i++){
JoseInsert(h, i, N-i+1);
}
/**************遍历双向链表***************/
TraverseList(h,N);
/***************出局函数************/
if(k > 1){
JoseDelete(h, N, k);
}
else//此时是用于当k<=1时采取的顺序输出失败者
{
for(i = 1; i < N; i++)
printf("出局的人为:%d号\n",i);
printf("***************获胜者为:%d号***************",N);
}
printf("\n");
printf("\n");
return 0;
}
文章作者:剑魄未改
相关链图片来源于csdn