来自:it笨笨 - 博客园
链接:http://www.cnblogs.com/iuices/archive/2011/11/07/2240325.html
(点击尾部阅读原文前往)
1、已知n个人(以编号1,2,3,...,n分别表示)围坐在一张圆桌周围,从编号为k的人开始报数,数到m的那个人出列,他的下一个人又从k开始报数,数到m的那个人出列,依次重复下去,直到圆桌的人全部出列。试用C++编写实现。
解析:本题就是约瑟夫环问题的实际场景,要通过输入n、m、k三个正整数,求出列的序列。这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素:
p->link=head;
解决问题的核心步骤如下:
(1)建立一个具有n个链节点、无头节点的循环链表。
(2)确定第一个报数人的位置。
(3)不断的从链表中删除链节点,直到链表为空。
答案:
#include
using namespace std;
typedef struct LNode
{
int data;
struct LNode *link;
}LNode,*LinkList;
//n为总人数,k为第一个开始报数的人,m为出列者喊到的数
void JOSEPHUS(int n,int k,int m)
{
//p为当前节点,r为辅助节点,指向p的前驱节点,list为头节点
LinkList p,r,list,curr;
//简历循环链表
p=(LinkList)malloc(sizeof(LNode));
p->data=1;
p->link=p;
curr=p;
for(int i=2;imalloc(sizeof(LNode));
t->data=i;
t->link=curr->link;
curr->link=t;
curr=t;
}
//把当前指针移动到第一个报数的人
r=curr;
while(k--)
r=p,p=p->link;
while(n--)
{
for(int s=m-1;s--;r=p,p=p->link);
r->link=p->link;
printf("%d->",p->data);
free(p);
p=r->link;
}
}
2、编程实现队列的入队/出队操作。
答案:
#include
using namespace std;
typedef struct student
{
int data;
struct student *next;
}node;
typedef struct linkqueue
{
node *first,*rear;
}queue;
//队列的入队 queue *insert(queue *HQ,int x)
{
node *s;
s=(node *)malloc(sizeof(node));
s->data=x;
s->next=NULL;
if(HQ->rear==NULL)
{
HQ->first=s;
HQ->rear=s;
}
else
{
HQ->rear->next=s;
HQ->rear=s;
}
return (HQ);
}
//队列的出队 queue *remove(queue *HQ)
{
node *p;
if(HQ->first==NULL)
printf("\n yichu");
else
{
p=HQ->first;
if(HQ->first==HQ->rear)
{
HQ->first=NULL;
HQ->rear=NULL;
}
else
{
HQ->first=HQ->first->next;
free(p);
}
return (HQ);
}
}
3、用两个栈实现一个队列的功能,请用C++实现。
解析:思路如下:
假设两个栈A和B,且都为空。
可以认为栈A提供入队列的功能,栈B提供出队列的功能。
入队列:入栈A。
出队列: