• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
qyk123
博客园    首页    新随笔    联系   管理    订阅  订阅
C语言实验报告四

题目:已知head指向一个不带头结点的环链表,链表中每个结点包含数据域(num)和指针域(link)。数据域存放整数,第i个结点的数据域值为i。编写函数,利用环形链表模拟猴子选大王的过程:从第一个结点开始循环“报数”,每遇到k的整数倍,就将相应的结点删除。如此循环直到链表中剩下一个结点,就是猴王。

实现方法及要求:

声明如下结构体
 struct list

{ int num;

  List *link;

};

思路:

  1. 定义结构体 list:

    • 用于表示环链表中的每个节点,包含猴子的编号 num 和指向下一个节点的指针 link。
  2. 创建环链表:

    • 使用 creat 函数创建一个包含 n 个节点的环链表,每个节点表示一个猴子。
    • 每个节点的编号从1到n,最后一个节点的 link 指向头节点,形成环状链表。
  3. 输出环链表:

    • 使用 printList 函数输出环链表的内容,以验证链表的正确性。
  4. 选猴王:

    • 使用 choice 函数实现猴子出局的逻辑。
    • 根据报数基数 k,循环遍历环链表,删除报数为 k 的猴子。
    • 最终输出剩下的猴子,即为猴王。
  5. 主函数:

    • 通过用户输入获取猴子个数 n 和出局基数 k。
    • 调用 creat 创建环链表,输出初始环链表。
    • 调用 choice 选出猴王,输出结果。

代码:

#include <stdio.h>
#include <malloc.h>   //函数malloc(),free()的头文件
#include <stdlib.h>   //函数exit()的头文件
/*声明结构体*/
struct list
{
	int num;
	list* link;
};
/* 建立环链表*/
list* creat(int n)   //参数n是结点个数,参数k是删除结点的基数
{
	int i = 1;         //为结点数据赋值
	list* head;      //定义指向链表起始地址的指针,作用是将第一个结点和最后一个结点连接起来
	list* pSet;      //开辟存储空间,建立结点
	list* pEnd;      //连接前后结点
	head = NULL;
	pEnd = head;
	do
	{
		pSet = (list*)malloc(sizeof(list));   //开辟存储空间
     if (pSet == NULL)
		{
			printf("没有足够空间,申请失败!");
			exit(0);
		}
		if (head == NULL)   head = pSet;    //如果是头结点,由head指向头结点
		else  pEnd->link = pSet;         //如果不是头结点,建立前一结点和新建结点的连接
		pSet->num = i;           //为结点的数据赋值
		if (pSet->num > n)
		{
			pEnd->link = head;
			free(pSet);
			break;            //结束循环
		}
		else
			pEnd = pSet;//pEnd建立连接后,指向新建结点
		    ++i;
	    } while (1);

	 return head;
     }
    /*输出环链的值*/
   void printList(list* head)
   {
	  list* pSet = head;

	  if (pSet == NULL)
	  {
	  	  printf("链表为空");
		  return;    // 退出函数,返回到主函数
	  }
	  while (1)
	  {
		  printf("%4d", pSet->num);
		  pSet = pSet->link;
		  if (pSet->link == head)
		  {
			  printf("%4d", pSet->num);
              pSet = pSet->link;

		if (pSet->link == head)
		{
			printf("%4d", pSet->num);
			break;
		}
	}
	printf("\n");
}
/*选猴王*/
void choice(list* head, int k)
{
	int i = 1;   //记录报数
	list* pEnd = head;
	while (pEnd->link != pEnd)
	{
		if (i % k == 0)        //整数倍时删除结点
		{
			pEnd->link = pEnd->link->link;
			printList(pEnd->link);

		}
		if (++i % k != 0)  pEnd = pEnd->link;
	}
	printf("\n猴王是编号%d的猴子!\n", pEnd->num);
}
int main()
{
	list* head;
	int n;       //n是结点个数
	int k;       //出局猴子数字的基数
	printf("请输入猴子个数n>0:");
	scanf("%d", &n);
	if (n <= 0)
	{
		printf("数据有误!");
		exit(0);
	}
	head = creat(n);    //调用建立环链表函数
	printList(head);  //输出环链表
	printf("请输入出局猴子数字的基数k:");
	scanf("%d", &k);
    	printList(head);  //输出环链表
	printf("请输入出局猴子数字的基数k:");
	scanf("%d", &k);
	choice(head, k);     //调用选猴王函数
    }

  • 程序通过链表的形式模拟了猴子围成一圈的情景,利用环链表的特性实现了猴子出局的循环过程。
  • 使用结构体表示节点,便于管理每个猴子的信息。
  • 注意在删除节点时,需要调整前一个节点的 link 指向,以维持环链表的结构。
  • 程序通过输出中间过程,包括环链表的建立和猴子的出局情况,使得执行过程更加清晰。
posted on 2024-02-20 08:56  qiyukun  阅读(25)  评论(0)    收藏  举报  来源
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3