简书内代码已上传GitHub:点击我 去GitHub查看代码
循环队列和链队列代码点击 循环队列 、链队列 查看
如果有错误大佬们留言指出啊!!
杨辉三角:
杨辉三角
一. 杨辉三角
简单的观察下,我们可以找到规律:
每一行的第一个数字和最后一个数字都是1
其余数字等于上一行该位置左右的两个数字和
如果把三角形以外的区域都看为0,我们可以把这个问题转化为不需要考虑边界的问题。直接用一个n元素的数组存储,计算什么都很方便。如果学了数据结构,我们会发现,同样的操作,用队列结构来实现,会更有优势。
二.思路
第一种:一个队列就行了,先把第一行”1“ 入队,用一个变量temp存储上一次队列弹出的值,这里默认初始时为0。对该队列进行遍历,每次把temp + 队头元素的值作为新队尾的值。每次遍历需要更新队列长度。也就是每次+1.
第二种: ...不想记录长度,反正空间多用点也没事,所以就双队列吧,两种方法思路都差不多。因为涉及到队列的交替使用,所以定义了一个长度为2的队列数组,把思路1中插入队尾的操作改为插入另一个队列的队尾,一次遍历后交换索引值。
三.C语言代码:
思路1
void PascalTriangle(int n){
LinkQueue q;
InitQueue(q);
// 一开始入队第一行元素
EnQueue(q, 1);
// cnt用于计行数
int cnt = 0, cnt1 = 0;
// temp用于保存上一次弹出的数据,初始为 0
int temp = 0;
while(cnt < n){
for(int p = 0 ; p < n - cnt - 1 ; ++p)
printf(" ");
// 当前行队列非空,遍历输出同时构造下一行队列
while(cnt1 <= cnt){
int e;
// 队头出队
DeQueue(q, e);
// 构造下一行
EnQueue(q, e + temp);
// 输出
printf("%4d", e);
// 更新左值
temp = e;
++cnt1;
}
cnt1 = 0;
// 行末特殊处理
EnQueue(q, temp + 0);
printf("\n");
// 行首+左结合元素为0
temp = 0;
++cnt;
}
}
思路2
void PascalTriangle(int n){
LinkQueue q[2];
InitQueue(q[0]), InitQueue(q[1]);
// 一开始入队第一行元素
EnQueue(q[0], 1);
// cnt用于计行数
int cnt = 0;
// temp用于保存上一次弹出的数据,初始为 0
int temp = 0;
// 控制两队列交替使用
int i = 0, j = 1;
while(cnt < n){
for(int p = 0 ; p < n - cnt - 1 ; ++p)
printf(" ");
// 当前行队列非空,遍历输出同时构造下一行队列
while(!QueueEmpty(q[i])){
int e;
// 队头出队
DeQueue(q[i], e);
// 构造下一行
EnQueue(q[j], e + temp);
// 输出
printf("%4d", e);
// 更新左值
temp = e;
}
// 行末特殊处理
EnQueue(q[j], temp + 0);
printf("\n");
//ClearQueue(q[i]);
// 行首+左结合元素为0
temp = 0;
// 交换队列编号
i = i ^ j , j = i ^ j , i = i ^ j;
++cnt;
}
}
输出结果:
结果
注释已经写的很全面,如果有不懂得留言或者私信问我呀。
每天进步一点,加油!
End
END