Joseph环-循环链表实现

#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;
}
 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值