之前已经学会了单链表的建立删除插入转置以及一些普通操作,双链表和单链表差不多,就是多了一个前驱指针,在许多操作中很方便,但是加了一个指针开销应该会大一些,总体上影响不大,这里开始讨论循环链表以及其他的一些数据结构。

 

1、已知n个人(以编号1,2,3,...,n分别表示)围坐在一张圆桌周围,从编号为k的人开始报数,数到m的那个人出列,他的下一个人又从k开始报数,数到m的那个人出列,依次重复下去,直到圆桌的人全部出列。试用C++编写实现。

    解析:本题就是约瑟夫环问题的实际场景,要通过输入n、m、k三个正整数,求出列的序列。这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素:

    p->link=head;

    解决问题的核心步骤如下:

    (1)建立一个具有n个链节点、无头节点的循环链表。

    (2)确定第一个报数人的位置。

    (3)不断的从链表中删除链节点,直到链表为空。

    答案:

    

 1 #include<iostream>
 2 using namespace std;
 3 typedef struct LNode
 4 {
 5     int data;
 6     struct LNode *link;
 7 }LNode,*LinkList;
 8 //n为总人数,k为第一个开始报数的人,m为出列者喊到的数
 9 void JOSEPHUS(int n,int k,int m)
10 {
11     //p为当前节点,r为辅助节点,指向p的前驱节点,list为头节点    LinkList p,r,list,curr;
12 
13     //简历循环链表    p=(LinkList)malloc(sizeof(LNode));
14     p->data=1;  
15     p->link=p;
16     curr=p;
17     for(int i=2;i<=n;i++)
18     {
19         LinkList t=(LinkList)malloc(sizeof(LNode));
20         t->data=i;
21         t->link=curr->link;
22         curr->link=t;
23         curr=t;
24     }
25     //把当前指针移动到第一个报数的人
26     r=curr;
27     while(k--)
28         r=p,p=p->link;
29     while(n--)
30     {
31         for(int s=m-1;s--;r=p,p=p->link);
32         r->link=p->link;
33         printf("%d->",p->data);
34         free(p);
35         p=r->link;
36     }
37 }
View Code

相关文章: