Joseph环-循环链表实现

来源:互联网 发布:极速mac修改器 编辑:程序博客网 时间:2024/06/05 14:20

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


原创粉丝点击