魔术师扑克牌问题[单循环链表]

这个程序刚开始写完的时候爆出了一堆bug。

有几点要说一下,作为初学者,应该是会不经意间就范的。

1.对循环链表的空判断。

当循环链表为空的时候,自身的下一指针指向自身。

2.释放链表后忘记对最后的指针进行循环设置。

 

#if 0
	程序名称:poker
	作用:模拟魔术师发牌
	描述:第一张牌为1,第二张牌就要从第二张重新数,为2.第三张就要从四张重新数。
	以此类推,大致如下,括号内的值表示位置:

	1(1) -> ?(2) -> 2(3) -> ?(4) -> ?(5) -> 3(6).....

#endif

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
	int data;
	struct node *next;
}Node, *LinkList;


#if 0
	这是注释,用宏来写注释不会出现嵌套注释出现的错误。比如 /*/**/*/ 就会出现错误。

	名称:CreateList[初始化链表]
	调用:CreateList(LinkList L)
	作用:生成并初始化13个节点的循环链表
	参数:LinkList L,头结点
#endif
void CreateList(LinkList L)
{
	LinkList p, r;
	int PokerNum = 12;				//牌数。每个花的牌总数为13张
									//由于在调用前申请了一个节点所以这里设置为12张

	L->data = 0;
	r = L;

	while (PokerNum)
	{
		p = (LinkList)malloc(sizeof(Node));
		if(!p)
		{
			printf("申请内存错误!");
			exit(1);
		}
		p->data = 0;
		r->next = p;
		r = p;						//尾插法

		PokerNum--;
	}
	r->next = L;					//将尾部的下一个指针指向头,形成循环链表
}


#if 0
	名称:CreatePork[设置牌序]
	调用:CreatePoker(LinkList L)
	作用:设置牌序,娱乐大众
#endif
void CreatePoker(LinkList L)
{
	LinkList p;
	int i;
	int CountNum = 2;				//每张牌计数

	p = L;
	p->data = 1;

	while(1)
	{
		for(i = 0; i<CountNum; ++i)
		{
			p = p->next;

			while(p->data != 0)		//当当前的节点有值时,越过。
			{
				p = p->next;
			}
		}

		if(p->data == 0)			//当当前节点无值时可以写入数据
		{
			p->data = CountNum;
			CountNum++;

			if(CountNum == 14)		//牌数够了就退出
			{
				break;
			}
		}
		
	}
}

void FreeList(LinkList L)
{
	LinkList p,l;
	p = l = L;

	printf("free:");
	while (l->next!=L &&l!=NULL)	//循环释放
	{
		l=l->next;
		printf("%d ",p->data);
		free(p);
		p = l;
	}
	L->next=L;						//设置头尾相连,为空表
}

void printlist(LinkList L)
{
	LinkList p;
	int i = 1;
	p = L;

	if(p == p->next)
	{
		printf("这是空表!");
		exit(1);
	}

	while (p->next != L)			//头尾相等时,为空表
	{
		printf("第 %d 张牌是 %d \n", i, p->data);
		p = p->next;
		i++;
	}
	printf("第 %d 张牌是 %d \n", i, p->data);
}

int main()
{

	LinkList L = (LinkList)malloc(sizeof(Node));

	if(!(L))
	{
		printf("申请内存错误!");
		exit(1);
	}

	printf("初始化链表\n");
	CreateList(L);
	printlist(L);

	printf("\n\n排序后:\n");
	CreatePoker(L);
	printlist(L);

	printf("释放后:\n");
	FreeList(L);

	return 0;

}

 

    原文作者:魔术师发牌问题
    原文地址: https://blog.csdn.net/MeeSong/article/details/11954855
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞