单向循环链表实现约瑟夫环(C语言)

#单向循环链表实现约瑟夫环

#include 
#include 		//提供malloc、free函数原型

/* 结点数据域数据类型 */
typedef int ElemType;

/* 链表结点结构体 */
typedef struct LNode
{
	ElemType data;       //数据域 
	struct LNode* next;  //指针域 
}LNode;

typedef LNode* LinkList; //指向链表结点的指针 


///*———————函数声明———————*///

LinkList Create(int m);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃创建一个含m个结点的单向循环链表	┃
┃并对每个结点编号后,返回其头结点	┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

void deleteLink(LinkList head,int s,int n,int m);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃	实现约瑟夫环的函数			┃
┃	参数表分别为        			┃
┃	head:单向环表的头指针 		┃
┃	s:从第s位开始        		┃
┃	n:间隔n位删除         		┃
┃	m:环表长度           		┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

///*———————主函数———————*///

int main()
{
	int m,s,n;
	LinkList head;  //为链表定义一个头指针 
	
	//输入m,s,n 
	printf("请输入m=");
	scanf("%d",&m);
	printf("\n请输入s=");
	scanf("%d",&s);
	printf("\n请输入n=");
	scanf("%d",&n);
	printf("\n");
	
	//创建链表并求解问题 
	head=Create(m); 
	deleteLink(head,s,n,m);
	
	system("pause"); 
	return 0;	 
 }

///*——————函数定义———————*///

LinkList Create(int m)
{
	LinkList rear,head,tmp;
	int i=0;
	
	rear=(LNode*)malloc(sizeof(LNode));
	if(rear==NULL)
	{
		printf("内存分配失败!");
	}
	head=rear;
	
	//尾插法创建一个有m个结点的单链表
	for(i=1;i<=m;i++)
	{
		tmp=(LNode*)malloc(sizeof(LNode));
		if(tmp==NULL)
		{
			printf("内存分配失败!");
		}
		tmp->data=i;	//为每个结点按顺序编号 
		rear->next=tmp;	//新节点插在尾巴
		rear=tmp;
	}
	
	//将尾结点和第一个节点连接起来,成为单向环表
	rear->next=head->next;
	
	//返回单向环表的头指针
	return head; 
}

void deleteLink(LinkList head,int s,int n,int m)
{
	int i,j;
	LinkList pre,tmp;
	pre=head->next;
	
	//找到起始结点 
	for(i=1;i<s;i++)
	{
		pre=pre->next;
	}
	
	for(j=1;j<=m;j++)   //循环m次,输出全部结点 
	{
		//循环间隔n的长度找到下一个待删除结点的pre 
		for(i=0;i<n-2;i++)
		{
			pre=pre->next;
		}
		
		printf("第%d位:%-3d\n",j,pre->next->data);  
		//输出待删除结点的编号
		
		tmp=pre->next;		  //现在pre为待删除结点的前一个结点,tmp为待删除结点
		pre->next=tmp->next;  //使tmp的前后结点连接
		free(tmp);            //删除tmp结点 
		pre=pre->next;        //指向下一结点
	}
}

你可能感兴趣的:(编程题)