数据结构上机实验记录——约瑟夫环

实验一

• 采用单向环表实现约瑟夫环。
• 请按以下要求编程实现:
• 从键盘输入整数m,通过create函数生成一个具有m个结点的单向环表。环表中的结点编号依次为1,2,……,m。
• 从键盘输入整数s(1<=s<=m)和n,从环表的第s个结点开始计数为1,当计数到第n个结点时,输出该第n结点对应的编号,将该结点从环表中消除,从输出结点的下一个结点开始重新计数到n,这样,不断进行计数,不断进行输出,直到输出了这个环表的全部结点为止。
• 循环链表(带有头结点的单向环表)
最后一个结点的指针域的指针又指回第一个结点(头结点)的链表。
循环链表示意
与单向链表的差别仅在于,判别链表中最后一
个结点的条件不再是 “ 后继是否为空 ” ,而是 “
继是否为头结点
”。
判别链表是否为空表的条件
• 循环链表的特点

  1. 从一个结点可找到链表中的任意一个结点;
  2. 判断是否为表尾结点的条件:p->next == L。
  3. 有时,用表尾指针表示循环链表
    示意图
    实现链表如下:
//约瑟夫环.cpp 

#include<stdio.h>
#include<malloc.h>
struct node
{
	int data;
	struct node* next;
}; 
struct node *p,*q,*head,*tail;
void create(int m,int n,struct node* head)
{
	if(m<=0||n>m)
	{
		free(head);
		printf("ERROR!");
	}
	else 
	{
		int i=1;
		tail=head;
		for(i=1;i<=m;i++)
		{
			p=(struct node* )malloc(sizeof(struct node));
			p->data=i;
			tail->next=p;//用tail表示当前链表中最后一个结点 
			p->next=head->next;//形成循环 
			tail=p;
		}
		p=p->next;//把p指到首元结点 
	}
}
int main()
{
	int m;//链表有m个结点 
	int s,n;//从第s个结点开始计数为1
	int count=1;//记录共输出了多少个数 
	int flag=0;//记录数到了1~n中的第几个结点 
	int i;//用于各种循环 
	printf("请按照形式“m s n”输入链表结点个数、开始节点及循环数:"); 
	scanf("%d %d %d",&m,&s,&n);
	head=(struct node* )malloc(sizeof(struct node));//头结点 
	head->data=-1,head->next=NULL;//初始化 
	create(m,s,head);//建立有m个结点的循环链表
	p=head->next;
	q=tail;//初始化 
	for(i=1;i<s;i++)
	{
		p=p->next;
		q=q->next;
	}//让p指在第s个结点上
	while(count<=m)
	{
		for(flag=1;flag<n;flag++)
		{
			p=p->next;
			q=q->next;
		}
		printf("%d ",p->data);
		q->next=q->next->next;
		free(p);//将输出过的节点删除并释放相应内存 
		p=q->next;
		count++;
	 } 
	 return 0;
 } 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值