杨辉三角形是形如:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
的三角形,其实质是二项式(a+b)的n次方展开后各项的系数排成的三角形,它的特点是左右两边全是1,从第二行起,中间的每一个数是上一行里相邻两个数之和。
使用《队列》的思想来实现杨辉三角的流程:
1>首先,需要初始化一个队列,即对头=队尾=0;
2>将第一行的元素1入队,接着操作第二行(一二行不需要求和操作,直接将元素入队即可);
3>从第三行开始,现在的对头指向N-1行,先将每行的固定元素1入队,然后循环操作求和过程:
将队首元素出队,并保存它的值temp;
获取当前队首的元素x,并进行temp=temp+x,且将temp入队;
4>循环结束后,队首在N-1行的最后一个元素处,现将其出队,然后将每行最后的固定元素1入队;
5>循环3、4步就可以输出杨辉三角形了。
注意:杨辉三角的特点是第N行的中间值等于N-1行两值的和,队列采用的是单进单出。
//使用队列输出杨辉三角
#include "stdafx.h"
#include<stdio.h>
#define MAXSIZE 50
#define FALSE 0
#define TRUE 1
typedef int QueueElemType;
typedef struct
{
QueueElemType element[MAXSIZE];
int front;//队头
int rear;//队尾
}SeqQueue;
void InitQueue(SeqQueue *Q)//初始化
{
Q->front = Q->rear = 0;
}
int EnterQueue(SeqQueue *Q, QueueElemType x)//入队
{
if ((Q->rear + 1) % MAXSIZE == Q->front)///队列已经满了
return FALSE;
Q->element[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAXSIZE;
return TRUE;
}
int DelQueue(SeqQueue *Q, QueueElemType *x)//出对
{
if (Q->front == Q->rear)
return FALSE;
*x = Q->element[Q->front];
Q->front = (Q->front + 1) % MAXSIZE;
return TRUE;
}
int GetHead(SeqQueue *Q, QueueElemType *x)//取对头元素
{
if (Q->front == Q->rear)
return FALSE;
*x = Q->element[Q->front];
return TRUE;
}
int IsEmpty(SeqQueue *Q)
{
if (Q->rear == Q->front)
return TRUE;
else
return FALSE;
}
//创建杨辉三角,N表示三角形的行数
void YangHuiTriangle(int N)
{
int n, i, x, temp;
SeqQueue Q;
InitQueue(&Q);
EnterQueue(&Q, 1);//第一行元素入队
for (n = 2; n <= N; n++)
{
EnterQueue(&Q, 1);//入队
for (i = 1; i <= n - 2; i++)
{
DelQueue(&Q, &temp);//出队的数赋给temp
printf("%d ", temp);
GetHead(&Q, &x);
temp = temp + x;
EnterQueue(&Q, temp);
}
DelQueue(&Q, &x);//出队
printf("%d ", x);
EnterQueue(&Q, 1);
printf("\n");
}
while (!IsEmpty(&Q))
{
DelQueue(&Q, &x);
printf("%d ", x);
}
}
void main()
{
int N;
printf("please input the N:");
scanf("%d", &N);
YangHuiTriangle(N);
printf("\n");
}
下面是网上找的思路,也可以参考一下:
使用队列解决这个问题有1个小的技巧:在两个1的两边增加两个0,通过0来标记这一层的结束。即:0 1 0 (杨辉三角的第一行,我们是从第一行开始的)
0 1 0
1 1
1 2 1
1 3 3 1
1 4 6 4 1
程序如下:
//遍历循环链表并打印
void printQueue(Queue *q)
{
for(int i = 0; i < Qlength(q);++i)
printf("%d ",q->data[(q->front+i+q->Qsize)%q->Qsize]);
printf("\n");
}
//输出杨辉三角的第n行的元素
void YangHuiTriangle(int n)
{
int level = n;
//printf("请输入");
Queue myQueue;
initQueue(&myQueue,level);
//初始化第一行:使用0作为一行结束的标记
enQueue(&myQueue,0);
enQueue(&myQueue,1);
enQueue(&myQueue,1);
enQueue(&myQueue,0);
int x,y;
for(int m = 1;m < level;++m)
{
do{
//将整个队列的前两个求和放入队尾,并删除队首元素
deQueue(&myQueue,&x);
getHead(&myQueue,&y);
enQueue(&myQueue,x+y);
}while(y!=0);
//填充队尾标记
enQueue(&myQueue,0);
}
printQueue(&myQueue);
}
这个做法很巧妙:先让元素出队,再获得后面的那个元素,然后再将二者相加以后入队,重复这个工作,直到遇见0为止。这个0既是上一层队列结束的0,又是这一层队列开始的0
。
最后附赠一份C++实现杨辉三角的代码:
//杨辉三角的C++代码
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i,j,t;
int a[11][11];
//左右两边全是1
for(i=1;i<11;i++)
{
a[i][1]=1;
a[i][i]=1;
}
for(i=1;i<11;i++)
{
if(i>=3)
{
for(t=2;t<i;t++)
{
a[i][t]=a[i-1][t-1]+a[i-1][t];
}
}
}
for(i=1;i<11;i++)
{
for(j=1;j<=i;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>