数据结构——循环链表、仅设尾指针的循环链表、约瑟夫环

  1 //循环链表,链表的尾结点的link域中不是NULL,而是存放了指针链表开始结点的指针
  2 ////设p是在循环链表中逐个结点检测指针,则在判断p是否达到链表的链尾时p->link == first
  3 
  4 
  5 //循环链表的结构定义
  6 typedef int DataType;
  7 typedef struct node//循环链表定义
  8 {
  9     DataType data;//结点数据
 10     struct node *link;//后继结点指针
 11 }CirNode, *CirList;
 12 
 13 //循环链表的插入算法
 14 int Insert(CirNode *first, int i, DataType x)
 15 {//将新元素x插入在循环链表中第i(1<=i)个结点位置。如果插入失败函数返回0,否则函数返回1.
 16     if(i<1)
 17         return 0;
 18     CirNode *p = first, *q;
 19     int k = 0;
 20     while(p->link != first && k< i-1)//定位于第i-1个结点,如果i超出表长度则插入到链尾
 21     {
 22         p = p->link;
 23         k++;
 24     }
 25     q = new CirNode;//创建新结点用q指示
 26     if(!q){cerr<<"存储分配错误!\n"; exit(1);}
 27     q->data = x;
 28     q->link = p->link;//将*q链接在*p之后
 29     p->link = p;
 30     return 1;//插入成功
 31 }
 32 

 33 //循环链表的删除算法
 34 int Remove(CirList& first, int i, DataType& x)
 35 {//将链表中的第i个元素删去,通过引用型参数x返回该元素的值
 36 //如果i不合理则删除失败,函数返回0, 否则函数返回1
 37     if(i<1)return 0;//i太小,不合理
 38     CirNode *p = first, *q;
 39     int k = 0;
 40     while(p->link != first && k < i-1)
 41     {
 42         p = p->link;
 43         k++;
 44     }
 45     //if(p->link == L)//i太大,被删结点不存在
 46      //   return 0;
 47     q = p->link;//用q保存被删结点地址
 48     p->link = q->link;//重新链接,将被删结点从链中摘下
 49     x = q->data;//取出被删结点的数据
 50     delete q;//释放结点
 51     return 1;
 52 }





 55 //仅设尾指针的循环链表
 56 //不用表头指针而用一个指向表尾结点的指针rear标识,可以将插入和删除的时间复杂度提高到O(l)
 57 //删除循环链表的指针p所指示的结点
 58 int Remove(CirNode* &p, DataType& x)
 59 {//将链表中的指针p所指示结点的元素删去,通过引用型参数x返回该元素的值
 60 
 61     CirNode *q = p->link;
 62     x = p->data;//取出p结点的元素
 63     p->data = q->data;//下一结点的元素复制给被删结点
 64     p->link = q->link;//重新链接,将下一结点从链中摘下
 65     delete q;//释放下一结点
 66     return 1;
 67 }
 68 //在循环尾端插入一个由newNode所指示的新结点
 69 int Insert(CirNode* &p, DataType& x)
 70 {//rear为尾指针
 71     CirNode *newNode;
 72     newNode->data = x;
 73     newNode->link = rear->link;
 74     rear->link = newNode;
 75 }

 78 //求解约瑟夫环问题
 79 
 80 void Josephus(CirNode* & Js, int n, int m)
 81 {
 82     CirNode *p = Js, *pre = NULL;
 83     for(int i = 0; i<n-1; i++)//执行n-1趟虚循环
 84     {
 85         for(int j = 0; j<m; j++)//令p向后移动m-1个结点
 86         {
 87             pre = p;
 88             p=p->link;
 89         }
 90         cout<<"出列的人"<<p->data<<endl;//输出结点*p的数据
 91         pre->link = p->link;
 92         delete p;//删去结点*p
 93         p = pre->link;
 94     }
 95     cout<<"最终优胜者是:"<<p->data<<endl;//输出结果
 96 }
 97 int main()
 98 {
 99     CirNode *clist, *last;
100     int n, m;
101     clist = new CirNode;//创建循环链表头结点
102     //if(!clist){cerr<<"存储分配失败!\n"; exit(1);}
103     clist->link = clist;
104     last = clist;//循环链表置空
105     cout<<"输入游戏者人数和报数间隔:";
106     cin>>n>>m;
107     for(int i=1; i<=n; i++)
108     {
109         last->link = new CirNode;//创建链表结点
110         if(!last->link){cerr<<"存储分配失败!\n"; exit(1);}
111         last = last->link;//逐个插入结点形成约瑟夫环
112         last->data = i;
113     }
114     Josephus(clist, n, m);//解决约瑟夫环问题
115     return 0;
116 }
117 //算法时间复杂度O(n*m)


约瑟夫环实现(C语言)

  1 #include"stdio.h"
  2 #include <malloc.h>
  3 
  4 //单链表结构体
  5 typedef struct Node
  6 {
  7     int index;
  8     int key;
  9     struct Node *next;
 10 }LinkNode, *LinkList;
 11 
 12 //创建链表
 13 LinkList CreatLinkList()
 14 {
 15     LinkList L;
 16     L = (LinkList)malloc(sizeof(Node));
 17     printf("请输入第一个人的密码:\n");
 18     int key;
 19     scanf_s("%d",&key);
 20     L->key = key;
 21     L->index = 1;
 22     L->next = L;
 23     Node *tail;
 24     Node *s;
 25     tail = L;
 26 
 27     printf("请输入构建循环单链表的长度-1:");//除去已经输入的第一个人
 28     int len;
 29     scanf_s("%d",&len);
 30 
 31     for (int i = 1; i < len; i++)
 32     {
 33         s = (Node *)malloc(sizeof(Node));
 34         scanf_s("%d", &s->key);
 35         s->index = i + 1;
 36         s->next = tail->next;
 37         tail->next = s;
 38         tail = s;
 39     }
 40     return L;
 41 }
 42 
 43 //约瑟夫环的实现
 44 void yuesef(LinkList L,int Password)
 45 {
 46     int count = 1;
 47     Node *p;
 48     Node *s, *r;
 49     p = L;
 50     while (p->next != p)
 51     {
 52         if (count == Password - 1)
 53         {
 54             printf("下标:%d  密码:%d\n", p->next->index, p->next->key);
 55             s = p->next;
 56             p->next = s->next;
 57             Password = s->key;
 58             while (Password == 1 && p->next != p)
 59             {
 60                 printf("下标:%d  密码:%d\n", p->next->index, p->next->key);
 61                 r = p->next;
 62                 p->next = r->next;
 63                 Password = r->key;
 64                 free(r);
 65             }
 66             free(s);
 67             count = 1;
 68             p = p->next;
 69         }
 70         else
 71         {
 72             p = p->next;
 73             count++;
 74         }
 75     }
 76     printf("下标:%d  密码:%d\n", p->index, p->key);
 77 }
 78 
 79 int main(void)
 80 {
 81     LinkList L;
 82     L = CreatLinkList();
 83     Node *p;
 84     p = L;
 85     printf("%d %d \n", p->index, p->key);
 86     p = p->next;
 87     //单链表的遍历
 88     while (p != L)
 89     {
 90         printf("%d %d \n", p->index, p->key);
 91         p = p->next;
 92     }
 93     printf("请输入初始关键值:\n");
 94     int Password;
 95     scanf_s("%d",&Password);
 96     yuesef(L, Password);
 97     getchar();
 98     getchar();
 99     return 0;
100 }






猜你喜欢

转载自blog.csdn.net/csdn_wanziooo/article/details/77917153