c_汉诺塔真相

输出图形的汉诺塔,蛮有意思。

其中的list.h是我从linux中提取的,参见:c_提取linux链表


#include "stdio.h"
#include "stdlib.h"
#include "list.h"


int high;
int interval=5;
LIST_HEAD(head1);
LIST_HEAD(head2);
LIST_HEAD(head3);
//
//#define DEBUG
struct Floor {
	int size;
	struct list_head list;
};

static inline 
int ListLen(struct list_head *head)
{
	int i = 0;
	struct list_head *plist;
	
	list_for_each(plist, head) 
	{
		i++;
	}
	return i;
}

void PrintHanoi(int high, int interval,
	struct list_head *head1,struct list_head *head2,struct list_head *head3)
{
	int tower1 = ListLen(head1);
	int tower2 = ListLen(head2);
	int tower3 = ListLen(head3);
	struct Floor *floor;
	int size,tmpSize;
	int i,j;
	
	for(i=0; i<high; i++)
	{
		if(i < high-tower1)
		{
			size=0;
		}
		else
		{
			size = list_empty(head1)?0:(floor = list_entry(head1->prev, struct Floor, list))->size;
#ifdef DEBUG			
			printf("size1:%d\n",size);
#endif			
			head1=head1->prev;			
		}
		for(j=0; j<high-size; j++)
		{
			printf(" ");
		}
		for(j=0; j<size; j++)
		{
			printf("* ");
		}
		
		if(i < high-tower2)
		{
			tmpSize=0;
		}
		else
		{
			tmpSize = list_empty(head2)?0:(floor=list_entry(head2->prev, struct Floor, list))->size;
#ifdef DEBUG			
			printf("size2:%d\n",size);
#endif			
			head2=head2->prev;
		}
		size += tmpSize;
		for(j=0; j<high*2+interval-size; j++)
		{
			printf(" ");
		}
		for(j=0; j<tmpSize; j++)
		{
			printf("* ");
		}
		size = tmpSize;
		if(i < high-tower3)
		{
			tmpSize=0;
		}
		else
		{
			tmpSize = list_empty(head3)?0:(floor=list_entry(head3->prev, struct Floor, list))->size;
#ifdef DEBUG			
			printf("size3:%d\n",size);
#endif			
			head3=head3->prev;			
		}
		size += tmpSize;
		for(j=0; j<high*2+interval-size; j++)
		{
			printf(" ");
		}
		for(j=0; j<tmpSize; j++)
		{
			printf("* ");
		}
		printf("\n");
		//while(1);
	}
}

void PrintHanoiCheckTower(char src, char dest)
{
	struct list_head *srcList, *destList;
	
	switch (src)
	{
		case 'A':
			{srcList = &head1;break;}
		case 'B':
			{srcList = &head2;break;}
		case 'C':
			{srcList = &head3;break;}
		default:
			printf("error!\n");
			while(1);
	}
			
	switch (dest)
	{
		case 'A':
			{destList = &head1;break;}
		case 'B':
			{destList = &head2;break;}
		case 'C':
			{destList = &head3;break;}
		default:
			printf("error!\n");
			while(1);		
	}
	list_move_tail(srcList->prev, destList);
	PrintHanoi(high, interval, &head1, &head2, &head3);
}

void Hanoi(int floor,char towerA,char towerB,char towerC)
{
	if(1 == floor)
	{
		printf("get %c to %c\n",towerA,towerC);
		printf("--------------------------------------->\n");
		PrintHanoiCheckTower(towerA, towerC);
		printf("--------------------------------------->\n");		
	}
	else
	{
		Hanoi(floor-1,towerA,towerC,towerB);
		printf("get %c to %c\n",towerA,towerC);
		printf("--------------------------------------->\n");		
		PrintHanoiCheckTower(towerA, towerC);
		printf("--------------------------------------->\n");		
		Hanoi(floor-1,towerB,towerA,towerC);
	}
}

int main()
{
	struct list_head *plist;
	struct Floor *floor;
	int i;
 
 	printf("input the tower of hanoi:\n");
 	scanf("%d",&high);
	
	for(i=0; i<high; i++)
	{
		floor = malloc(sizeof(struct Floor));
		if(NULL == floor)
		{
			printf("malloc err! stop!!!--->>\n");
		}
		floor->size = high-i;
		list_add_tail(&floor->list, &head1);
	}
#if 0
	list_for_each(plist, &head1) 
	{
		floor = list_entry(plist, struct Floor, list);
		printf("size: %d\n",floor->size);
	}

	printf("*********************************************--->\n");

	list_move_tail(head1.prev, &head2);
	list_for_each(plist, &head1) 
	{
		floor = list_entry(plist, struct Floor, list);
		printf("size: %d\n",floor->size);
	}
	printf("*********************************************--->\n");
	list_for_each(plist, &head2) 
	{
		floor = list_entry(plist, struct Floor, list);
		printf("size: %d\n",floor->size);
	}
	printf("*********************************************--->\n");
#endif
	//while(1);
	PrintHanoi(high, interval, &head1, &head2, &head3);
	
	Hanoi(high,'A','B','C');
	//Hanoi(high, &head1, &head2, &head3);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值