打印杨辉三角。杨辉三角是一个由数字排列成的三角形数表,一个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;
}
结果: