#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
//宏定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
//typedef char ElemType;
/* 结点类型* */
typedef struct LNode{
// int circle_id; //每个人循环数
int original_id; //每个人原来的id
int code; //每个人的密码
struct LNode *next;
}LNode,*LinkType;
/* 链表类型 */
typedef struct{
LinkType head,tail;
int length;
}LinkList;
/*构建一个新结点 test OK*/
Status MakeNode(LinkType &p,int y,int z)
{
p=(LinkType)malloc(sizeof(LNode));
if(!p) return FALSE;
//p->circle_id=x;
p->original_id=y;p->code=z;p->next=NULL;return TRUE;
}
/* 释放结点 */
void FreeNode(LinkType &p)
{
free(p);
}
/* 复制结点 */
LinkType Copy(LinkType p)
{
LinkType s;
s=(LinkType)malloc(sizeof(LNode));
if(!s) return NULL;
//s->circle_id=p->circle_id;
s->original_id=p->original_id;s->code=p->code;s->next=NULL;return s;
}
int Origin_id(LinkType p)
{
if(!p) return FALSE;
return (p->original_id);
}
int Id_code(LinkType p)
{
if(!p) return FALSE;
return (p->code);
}
/* 结点的后继 */
LinkType SuccNode(LinkType p)
{
LinkType s;
if(!p) return NULL;
s=p->next;
return s;
}
/* 结点的前继 */
LinkType PreNode(LinkType p,LinkList L)
{
LinkType s;
if(!p||!L.head||L.length<1) return NULL;
if(p==L.head) return L.tail;
s=L.head;
while(s!=L.tail&&s->next!=p) {
s=SuccNode(s);
}
if(s->next==p) {return s;}
return NULL;
}
Status InitList(LinkList &L,int x,int y); //初始化链表
void DestroyList(LinkList &L);//销毁链表
Status ListEmpty(LinkList L); //链表是否为空
int ListLength(LinkList L); //链表的长度
LinkType GetElemPos(LinkList L,int pos);// 查找第pos个元素的指针
Status LocateElem(LinkList L,int j,LinkType &q); //
void Append(LinkList &L,LinkType s); //在已存在的链表L末尾添加指针s指向的结点
void InsertAfter(LinkList &L,LinkType q,LinkType s); //在已存在的链表L中q所指示的结点之后插入指针s所指向的结点
void ListTraverse(LinkType p,Status (*visit)(LinkType));//从p(p!=NULL)指示的结点开始,依次对每个结点调用函数visit
/* 初始化链表 test OK */
Status InitList(LinkList &L,int x,int y)
{
LinkType p;
if(MakeNode(p,x,y)) {
L.head=L.tail=p;p->next=L.head;L.length=1;
return OK;
}
else return FALSE;
}
/* 销毁链表 */
void DestroyList(LinkList &L)
{
LinkType p,q;
p=L.head;
while(p!=L.tail) {q=p;p=SuccNode(p);FreeNode(q);}
free(p);
L.head=L.tail=NULL;
}
/* 查找第pos个元素的指针 */
LinkType GetElemPos(LinkList L,int pos)
{
LinkType p;
int k;
if(!L.head||pos<1||pos>L.length) return NULL;
else if (pos==L.length) return L.tail;
else{
p=L.head;k=1;
while(p!=L.tail&&k<pos) {p=SuccNode(p);k++;}
return p;
}
}
/* 在链表末尾添加结点 */
void Append(LinkList &L,LinkType s)
{
if(L.head&&s){
if(L.tail!=L.head) {L.tail->next=s;}
else {L.head->next=s;}
s->next=L.head;
L.tail=s;
L.length++;
// printf("s->id:%d",s->code);
}
}
/* 删除结点Q P为Q结点的前继 */
Status Delete(LinkList &L,LinkType p,LinkType q)
{
if(!L.head) return FALSE;
else{
p->next=q->next;
if(q==L.head) {L.head=q->next;}
else if(q==L.tail) {L.tail=p;}
else {;}
free(q);
L.length--;
}
}
/* 遍历链表的结点 */
void ListTraverse(LinkList L,LinkType p,Status (*visit)(LinkType))
{
while(p!=L.tail->next) {(*visit)(p);p=SuccNode(p);}
}
typedef LinkList JosephLink;
/* 创建Joseph环 */
void CreatJosephLink(JosephLink &T,int id[],int passwd[],int num)
{
int i;
LinkType p;
T.head=T.tail=NULL;
T.length=0;
if(InitList(T,id[0],passwd[0])){
for(i=1;i<num;i++)
{
if(MakeNode(p,id[i],passwd[i]))
{
Append(T,p);
}
}
}
}
/* Joseph游戏开始 */
void StartJosephLink(JosephLink &T,int a[],int num)
{
int m,i,j=0;
LinkType p,q,r;
printf("请输入初始的报数值m:\t");
scanf("%d",&m);
q=GetElemPos(T,1); //获取循环链表的头指针
while(T.length>=2)
{
printf("L的长度为%d\n",T.length);
for(i=1;i<m;i++)
{
q=SuccNode(q); //获取节点q的后继
}
p=PreNode(q,T); //获取节点q的前驱
m=Id_code(q);
printf("m:%d\n",m);
a[j]=q->original_id; //打印出列节点的id
r=SuccNode(q);
Delete(T,p,q); //删除节点q
q=r;
j++;
}
a[num-1]=T.head->original_id;
}
void WriteElem(LinkType p)
{
printf("%d",p->code);
}
Status WriteSetElem(LinkType p)
{
printf(",");WriteElem(p);
return OK;
}
void PrintSet(JosephLink T)
{
LinkType p;
Status stat;
p=GetElemPos(T,1); //取第一个元素的地址
if(p) {
WriteElem(p);p=SuccNode(p);
}
ListTraverse(T,p,WriteSetElem);
}
int main(int argc, char *argv[])
{
JosephLink huahua;
huahua.head=huahua.tail=NULL;
huahua.length=0;
int n,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
{
a[i]=i+1;
}
int passwd[n];
for(i=0;i<n;i++){
printf("第%d个人的密码为:\t",i+1);
scanf("%d",&passwd[i]);
}
CreatJosephLink(huahua,a,passwd,n);
PrintSet(huahua);
StartJosephLink(huahua,a,n);
for(i=0;i<n;i++){
printf("%d,",a[i]);
}
system("PAUSE");
return 0;
}
Joseph环-循环链表实现
最新推荐文章于 2022-12-28 21:05:20 发布