0
点赞
收藏
分享

微信扫一扫

数据结构与算法之线性表的应用:选首领


数据结构与算法之线性表的应用:选首领

  • ​​前提条件​​
  • ​​题目描述​​
  • ​​算法步骤​​
  • ​​创建一个单循环链表(线性表)​​
  • ​​C语言实现​​
  • ​​选首领​​
  • ​​C语言实现​​
  • ​​完整代码​​
  • ​​输出结果​​

前提条件

  • 熟悉C语言与指针
  • 熟悉数据结构与算法

题目描述

题目:选首领。
N个游戏者围成一圈,从第一个人开始顺序报数1,2,3。凡报到3者退出圈子,最后留在圈中的人为首领(赢家)。

算法步骤

创建一个单循环链表(线性表)

使用头插法创建循环链表,以5个游戏者(结点)举例,如下图。

数据结构与算法之线性表的应用:选首领_c语言

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者退出圈子,即对应了链表的删除操作。

数据结构与算法之线性表的应用:选首领_指针_02

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;
}

输出结果

数据结构与算法之线性表的应用:选首领_c语言_03


举报

相关推荐

0 条评论