杨辉三角的打印---------数据结构典型例题

杨辉三角的打印---------数据结构典型例题

现在,给定一个数字N,需要打印N行的杨辉三角

注意:

杨辉三角实际上是
C n m 这 个 问 题 的 解 决 方 法 C^m_n \\ 这个问题的解决方法 Cnm
我认为:如果单独给出一个 C n m C^m_n Cnm的话,应该利用阶乘来进行实现,但是在这里,它要求打印杨辉三角,使用这种“笨”方法显然是行不通。

重点是要利用已经计算的结果。

杨辉三角给出了答案:

下面的一个等于上面两个的和,所以我们可以利用上一步的结果来加快这一次的运算。

杨辉三角的推倒:

C n m = C n − 1 m − 1 + C n − 1 m C^m_n = C_{n-1}^{m-1} + C_{n-1}^{m} Cnm=Cn1m1+Cn1m

可以利用组合数的公式证明:

从M中选出N个(假设有一个元素X)

  1. 选到 X 的情况: C n − 1 m − 1 C_{n-1}^{m-1} Cn1m1
  2. 没有选到 X 的情况: C n − 1 m C_{n-1}^{m} Cn1m

得到证明。

代码实现(queue)

我发现了一个特征:

栈是要一直记录之前的东西,然而目前仅仅专注现在的栈顶。

但是队列是随着过程的进行,前面的会被后面的所替代!!

最后面的一个 1 我自己给补上。

队列的实现请参照我之前写的博文数据结构实现——循环队列

//注意:杨辉三角有一点离谱,所以奉劝各位见好就收,打印20行以内。
#include <stdio.h>
#include <stdlib.h>
typedef int Elem;
typedef struct Queue
{
Elem *data;
int head;
int tail;
int size;//仅仅是一个功能,程序的判空,判断满并不依赖。
int MAX_SIZE;//是真正申请的最大值,实际存放MAX_SIZE-1个。
}Queue;
//函数原形声明
Queue *Creat(int max);
int Size(Queue* Q);
Elem GetTail(Queue *Q);
Elem GetHead(Queue *Q);
int Pop(Queue *Q);
int Push(Queue *Q, Elem e);
int Full(Queue* Q);
int Empty(Queue *Q);
int Destroy(Queue* Q);
Queue *Creat(int max)
{
if(max <= 0)
return NULL;
Elem *D = (Elem*)calloc(max + 1, sizeof(Elem));
if(!D)
return NULL;
Queue *Q = (Queue*)malloc(sizeof(Queue));
if(!Q)
{
free(D);
return NULL;
}
Q->MAX_SIZE = max + 1;
Q->data = D;
Q->head = 0;
Q->tail = 0;
Q->size = 0;
return Q;
}
int Destroy(Queue* Q)
{
if(!Q)
return 0;
free(Q->data);
free(Q);
return 1;
}
int Empty(Queue *Q)
{
if(Q->head == Q->tail)
return 1;
else
return 0;
}
int Full(Queue* Q)
{
if((Q->tail+1)%Q->MAX_SIZE == Q->head)
return 1;
else
return 0;
}
int Push(Queue *Q, Elem e)
{
if(Full(Q))
return 0;
Q->data[Q->tail] = e;
Q->tail = (Q->tail + 1)%Q->MAX_SIZE;
Q->size += 1;
return 1;
}
int Pop(Queue *Q)
{
if(Empty(Q))
return 0;
Q->head = (Q->head + 1) % Q->MAX_SIZE;
Q->size -= 1;
return 1;
}
Elem GetHead(Queue *Q)
{
if(Empty(Q))
{
*(int *)NULL;//专门让程序crash
}
return Q->data[Q->head];
}
Elem GetTail(Queue *Q)
{
if(Empty(Q))
{
*(int *)NULL;//专门让程序crash
}
int t;
t = Q->tail;
t -= 1;
if(t >= 0)
return Q->data[t];
else
{
return Q->data[Q->MAX_SIZE-1];
}
}
int Size(Queue* Q)
{
return Q->size;
}
int main()
{
int N;
scanf("%d",&N);
Queue *Q = Creat(N);
Push(Q,1);
printf("%6d",1);
putchar('\n');
for(int i = 2; i <= N; i++)
{
int last = 0;
for(int j = 1; j <= i - 1; j++)
{
int t = 0;
t = GetHead(Q);
Pop(Q);
Push(Q,t+last);
printf("%6d",t+last);
last = t;
}
Push(Q,1);
printf("%6d",1);
putchar('\n');
}
Destroy(Q);
return 0;
}
posted @   心坚石穿  阅读(195)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示