链式表示的队列——链式队列2——杨辉三角问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36669549/article/details/84573610

打印杨辉三角。杨辉三角是一个由数字排列成的三角形数表,一个8阶的杨辉三角如下所示。

                                1
                             1     1
                          1     2     1
                       1     3     3     1
                    1     4     6     4     1
                 1     5    10    10     5     1
              1     6    15    20    15     6     1
           1     7    21    35    35    21     7     1

【分析】

杨辉三角,是二项式系数在三角形中的一种几何排列,在中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623----1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。

1.杨辉三角的性质
(1)第一行只有一个数;
(2)第i行有i个数;
(3)第i行最左端和最右端的数均为1;
(4)每个数等于上一行的左右两个数相加,即第n行的第i个元素等于第n-1行的第i-1和元素和第i个元素之和。
2.构造队列杨辉三角的第i行元素是根据第i-1元素得到的,因此可以用队列先保存上一层元素,然后将队列依次出队得到下一层的元素。构造杨辉三角分为2个部分;两端元素值为1的部分是已知的,剩下的元素是需要构造的部分。

以第8行元素为例,利用队列来构造杨辉三角(假设Q是顺序循环队列)。

(1)在第8行,第一个元素入队,EnQueue(&Q,1).
(2)第8行中的中间6个元素可以通过已经入队的第7行元素得到。首先取出队头元素并将其出队Dequeue(&Q,&t);再次将该元素存入临时数组中(用于打印输出),temp[k++]=t; t就是上一行的左边那一个元素;然后取出右边那一个元素GetHead(Q,&e), e为队头元素,但并不是将其出队,因为下一次操作还要用到它;然后将左边的元素和右边的元素相加t=t+e; 得到本层元素;最后将元素t入队,EnQueue(&Q,t); 
(3)第7行最后一个元素出队,DeQueue(&Q,&t), 就是将上一行的最后一个1出队。
(4)第8行最后一个元素入队,EnQueue(&Q,1),就是将本行最后一个1入队。

至此,第8行的所有元素都已经入队。其它行的入队操作类似。

注意在循环结束后,还有最后一行在队列里。在最后一行元素入队之后。要将其输出。为了输出杨辉三角的每一行,需要设置一个临时数组temp[MaxSize]用来存储每一行的元素,然后在结束时输出该行元素。
LinkQueue.h

#pragma once
#include <iostream>
using namespace std;
#include <malloc.h>
typedef int DataType;
typedef struct QNode
{
	DataType data;
	struct QNode* next;

}LQNode,*QueuePtr;
typedef struct 
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;
//初始化链式队列
void InitQueue(LinkQueue *LQ)
{
	LQ->front = LQ->rear = (LQNode*)malloc(sizeof(LQNode));
	if (LQ->front==NULL)
	{
		exit(-1);
	}
	LQ->front->next = NULL;

}
//判断链式队列是否为空
int QueueEmpty(LinkQueue LQ)
{
	if (LQ.rear->next==NULL)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//将元素e入队
int EnQueue(LinkQueue *LQ, DataType e)
{
	LQNode *s;
	s = (LQNode*)malloc(sizeof(LQNode));
	if (!s)
	{
		exit(-1);
	}
	s->data = e;
	s->next = NULL;
	LQ->rear->next = s;
	LQ->rear = s;
	return 1;
}

int DeQueue(LinkQueue *LQ, DataType *e)
{
	LQNode *s;
	if (LQ->front==LQ->rear)
	{
		return 0;
	}
	else
	{
		s = LQ->front->next;
		*e = s->data;
		LQ->front->next = s->next;
		if (LQ->rear==s)
		{
			LQ->rear = LQ->front;
		}
		free(s);
		return 1;
	}
}

int GetHead(LinkQueue LQ, DataType *e)
{
	LQNode *s;
	if (LQ.front==LQ.rear)
	{
		return 0;
	}
	else
	{
		s = LQ.front->next;
		*e = s->data;
		return 1;
	}
}

void ClearQueue(LinkQueue *LQ)
{
	while (LQ->front!=NULL)
	{
		LQ->rear = LQ->front->next;
		free(LQ->front);
		LQ->front = LQ->rear;
	}
}

main.cpp

#define MAXSIZE 100
#include "LinkQueue.h"
#include <iomanip>
void PrintArray(int a[],int n,int N);
void YangHuiTriangle(int N);

void main()
{
	int n;
	cout << "请输入要打印的行数:n=: ";
	scanf("%d", &n);
	YangHuiTriangle(n);


	system("pause");

}

void YangHuiTriangle(int N)
{
	int i, k, n;
	DataType e, t;
	int temp[MAXSIZE];
	LinkQueue Q;
	k = 0;
	InitQueue(&Q);
	EnQueue(&Q, 1);
	for (n = 2; n <= N;n++)
	{
		k = 0;
		EnQueue(&Q, 1);
		for (i = 1; i <= n - 2;i++)
		{
			DeQueue(&Q, &t);
			temp[k++] = t;
			GetHead(Q, &e);
			t = t + e;
			EnQueue(&Q, t);
		}
		DeQueue(&Q, &t);
		temp[k++] = t;
		PrintArray(temp, k, N);
		EnQueue(&Q, 1);
	}

	k = 0;
	while (!QueueEmpty(Q))
	{
		DeQueue(&Q, &t);
		temp[k++] = t;
		if (QueueEmpty(Q))
		{
			PrintArray(temp, k, N);
		}
	}
}

void PrintArray(int a[], int n, int N)
{
	int i; 
	static int count = 0;
	for (i = 0; i < N - count;i++)
	{
		cout << "   ";//三个空格
	}
	count++;
	for (i = 0; i < n;i++)
	{
		cout << setw(6)<< a[i];
	}
	cout << endl;
}

结果:

猜你喜欢

转载自blog.csdn.net/baidu_36669549/article/details/84573610