数据结构与算法之线性表的应用:选首领
- 前提条件
- 题目描述
- 算法步骤
- 创建一个单循环链表(线性表)
- C语言实现
- 选首领
- C语言实现
- 完整代码
- 输出结果
前提条件
- 熟悉C语言与指针
- 熟悉数据结构与算法
题目描述
题目:选首领。
N个游戏者围成一圈,从第一个人开始顺序报数1,2,3。凡报到3者退出圈子,最后留在圈中的人为首领(赢家)。
算法步骤
创建一个单循环链表(线性表)
使用头插法创建循环链表,以5个游戏者(结点)举例,如下图。
C语言实现
LinkList create_list(int n)
/*创建一个结点数为n的单循环链表,返回值为游戏编号为1的结点的指针*/
{
LinkList head,p;
int k; //计数器k,计算游戏人数
head = (NODE *)malloc(sizeof(NODE));/*创建循环链表的第一个结点*/
if(!head){
printf("memory allocation error!\n");
return NULL;
}
head->id=1;
head->next = head;
for (k = n; k > 1; k--)
/* 头插法创建循环链表的其余n-1个结点 */
{
p = (NODE *)malloc(sizeof(NODE));/*创建循环链表的第一个结点*/
if(!p){
printf("memory allocation error!\n");
return NULL;
}
p->id=k;
p->next = head->next;
head->next=p;
}
return head;
}
选首领
思路:报数为2的下一个结点,即为报数为3的结点。凡报到3者退出圈子,即对应了链表的删除操作。
C语言实现
void play(LinkList head,int n)
/*选首领(赢家)*/
{
LinkList p,s;
int c=0,k;//c计算报数,k计算游戏人数
p=head;
c=1;
k=n;
while (k>1)
{
if(c==2)
/*当c等于2时,p指向的结点的后继即为将被删除的结点*/
{
s=p->next;
p->next=s->next;
printf("%4d",s->id);
free(s);
c=0;
k--;
}
c++;
p=p->next;
}
printf("\n%4d was the winner.",p->id); /*输出赢家编号*/
}
完整代码
/*
题目:选首领。N个游戏者围成一圈,从第一个人开始顺序报数1,2,3。凡报到3者退出圈子,最后留在圈中的人为首领(赢家)。
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int id;/* 数据域(游戏者编号) */
struct node *next; /*指针域*/
}NODE,*LinkList;
LinkList create_list(int n)
/*创建一个结点数为n的单循环链表,返回值为游戏编号为1的结点的指针*/
{
LinkList head,p;
int k; //计数器k,计算游戏人数
head = (NODE *)malloc(sizeof(NODE));/*创建循环链表的第一个结点*/
if(!head){
printf("memory allocation error!\n");
return NULL;
}
head->id=1;
head->next = head;
for (k = n; k > 1; k--)
/* 头插法创建循环链表的其余n-1个结点 */
{
p = (NODE *)malloc(sizeof(NODE));/*创建循环链表的第一个结点*/
if(!p){
printf("memory allocation error!\n");
return NULL;
}
p->id=k;
p->next = head->next;
head->next=p;
}
return head;
}
void play(LinkList head,int n)
/*选首领(赢家)*/
{
LinkList p,s;
int c=0,k;//c计算报数,k计算游戏人数
p=head;
c=1;
k=n;
while (k>1)
{
if(c==2)
/*当c等于2时,p指向的结点的后继即为将被删除的结点*/
{
s=p->next;
p->next=s->next;
printf("%4d",s->id);
free(s);
c=0;
k--;
}
c++;
p=p->next;
}
printf("\n%4d was the winner.\n",p->id); /*输出赢家编号*/
}
void output(LinkList head)
/*输出链表中结点的数据*/
{
LinkList p;
p=head;
do{
printf("%4d",p->id);
p=p->next;
}while (p!=head);
printf("\n");
}
int main()
{
LinkList headptr;
int n;
printf("input the number of players:");
scanf("%d",&n);
headptr = create_list(n); /*创建单循环链表*/
if (headptr)
/*输出单循环链表中的结点信息*/
{
output(headptr);
play(headptr,n);
}
system("pause");
return 0;
}
输出结果