杨辉三角

杨辉三角的思路就是上一层的相邻两数相加得到下一层的数
那么可以使用两个队列来进行数的存储和计算
A队列的数两两相加导入B队列
基本思路(多层):首先初始化A队列,即杨辉三角顶层
接着设置两个参数L,R用于存储出队数字,再设一个参数T = L + R 用于计算下一层数字
实际上每次出队的数字仅给R
打印R,即打印本层的数字
由于杨辉三角下层第一个数 = 0 + 上层一个数,所以L初始总为0
那么T = L + R = 1就可以作为下一层的第一个数(入队Q2)
接着把R 赋予 L,再出队一个数给R
循环出队,赋予,相加,入队,实现本层数字的打印和下一层数字的计算、保存
这样当到最后一个数时,下层的最后一个数 = 上层的最后一个数 + 0
所以此时只设置 T = L
一层的计算结束后,我们需要将
我们以4层杨辉为例
1
1 1
1 2 1
1 3 3 1
初始化A队列 = [1]
A出队给 R, R = 1,打印R,第一层打印完成
T = L + R = 0 + 1 = 1,入队B,得到第二层第一个数
R赋给L ,接着计算下一个数,而下一个数已经是第二层的最后一个数,因此T = L = 1,入队B
此时 B队列 = [1, 1]

将B 队列 赋予A队列,重复上一步
A = [1, 1]
打印第二层
L = 0, R = 1, T = L + R = 1,
R赋予L,A出队给R,L = 1, R = 1,T = L + R = 2
最后一个数,T = L = 1
于是B队列 = [1, 2, 1]
将B 队列赋予A队列
如此反复

//两队列的内存空间因需要增加,非固定
#include 
#include 
#include 

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#define ERROR 1
#define OK 0
#define OVERFLOW 1

typedef int QElemType;
typedef int Status;
int tag = 0;		//题目要求标志域 

typedef struct 
{
	QElemType *base; // 动态分配存储空间
	int front;   	// 头指针,若队列不空,指向队列头元素
	int  rear;  	// 尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;

Status InitQueue(SqQueue &Q,int MAXSIZE)	//构造一个空队列Q
{   
	Q.base = (QElemType *) malloc (MAXSIZE *sizeof (QElemType));
    if (!Q.base)
		exit (OVERFLOW);		//存储分配失败
    Q.front = Q.rear = 0;		//初始头尾指针指向同一位置 
    return OK;
}

Status EnQueue(SqQueue &Q, int e,int MAXSIZE)  //插入元素e为Q的新的队尾元素
{  
    if( ((Q.rear+1) % MAXSIZE) == Q.front )
    {
    	if( ((Q.rear+1) / MAXSIZE) == 0 )
		{
			tag = 0;	//队列为空 
		}
		if( ((Q.rear+1) / MAXSIZE) == 1 )
		{
			tag = 1;	//队列已满 
			return ERROR;
		}
	}
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear+1) % MAXSIZE;
    tag = 2;		//队列未满 
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e,int MAXSIZE)	//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK
{
	e = Q.base[Q.front];
	Q.front = (Q.front+1) % MAXSIZE;
	return OK;
}

//--------------------------杨辉三角算法-----------------------------
void YhTriangle(int Level)
{
	SqQueue Q1,Q2;		//设置两个队列
	QElemType Lnum = 0, Rnum = 1, Totalnum;	//设置两个变量用以记录出队数据,tatolnum记录两数之和
	int level = 1;		//设置变量记录当前输出层数
	int kong;		//空格,调整输出格式
	int i;		//记录每层数据个数 
	
	InitQueue(Q1,2);     //初始化队列
	EnQueue(Q1,Rnum,2);	//预设置第一层 
	
	if(Level == 1)		//一层杨辉三角,输出预设 
	{
		DeQueue(Q1,Rnum,level+1);
		printf("%d",Rnum);
	}
	if(Level > 1)		//多层杨辉三角 
	{
		for(level = 1 ; level <= Level ; level++)
		{
			for(kong = 0 ; kong < Level - level ; kong++)
			{
				printf("  ");	//输出空格,调整输出格式 
			}
			
			if(level < Level) 
			{
				Lnum = 0;
				InitQueue(Q2,level+2);     //初始化队列,用以保存下一层数据 
				for(i = 0 ; i < level ; i++)	//第n层,有n个元素
				{ 
					DeQueue(Q1,Rnum,level+1);
					if(Rnum < 10)		//排版用 
						printf("%d   ",Rnum);
					else
						printf("%d  ",Rnum);
					Totalnum = Lnum + Rnum;		//上一层两个数相加为下一层的数 
					EnQueue(Q2,Totalnum,level+2);	//入队列
					Lnum = Rnum;	//将位置腾出,为下一个数据做准备
					if(i == level - 1)		//下层的最后一个数,实际上就是1,就是上层的最后一个数1(1+0 = 1)
					{
						Totalnum = Lnum;
						EnQueue(Q2,Totalnum,level+2);
					}
				}
				InitQueue(Q1,level+2);     //实现每次均为Q1出队该层数据
				Q1 = Q2;		//Q2需入队下一层数据 
			}
			
			if(level == Level)		//当前为最后一层,无需使用数据 
			{
				for(i = 0 ; i < level ; i++)	//第n层,有n个元素
				{
					DeQueue(Q1,Rnum,level+1);
					if(Rnum < 10)		//排版用 
						printf("%d   ",Rnum);
					else
						printf("%d  ",Rnum);
				}
			}
			printf("\n"); 	//换行,下一层 
		}
	}
}
//--------------------主函数-------------------------- 
int main(int argc, char** argv)
{
	int level;
	printf("需打印几层杨辉三角?\n");
	scanf("%d",&level);
	YhTriangle(level);
	return 0; 
}

你可能感兴趣的:(算法讲解)