引入
未完待续…
高树靡阴,独木不林。
未完待续…
未完待续…
未完待续…
未完待续…
八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

传说越南河内某间寺院有三根银棒
若传说属实,僧侣们需要 $2^{64}-1$步才能完成这个任务
若他们每秒可完成一个盘子的移动,就需要 5845 亿年才能完成。整个宇宙现在也不过 137 亿年。

(图片来自于维基百科)
递归学习过编程的基本上都应该大体知道,但是递归的效率并不高,我们通常使用迭代循环,但我在探索未知的情况下,递归可能会更好。我们通过斐波那契数列来了解一下递归。
因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34…
即开始有一对儿兔子,然后3个月后兔子长大了,这对兔子会生一对儿兔子,之后的每个月这对儿兔子又生一对儿,假设兔子不会死亡,那么 N 个月后有多少对儿兔子。
数列:1、1、2、3、5、8、13、21、34…
找到数列的规律之后,我们发现,3号数是1号+2号,6号数是4号+5号,即该数前两个数的和。
#include <stdio.h>
int main(){
int f1=1,f2=1,f3;
//将第1、2个月的数先赋值,作为计算基底
printf("%12d\t%12d\t",f1,f2);
//由于已经赋值了,所以就先输出
for(int i=3;i<41;i++){
f3=f1+f2;
printf("%12d\t",f3);
//利用循环输出第三个月的数,也就是前两个月的和
if(i%4==0){
printf("\n");
}
//判断换行
f1=f2;
f2=f3;
//将用于相加的两个数向前推移
}
}
前面我们讲了,如何初始化一个循环队列,今天我们就来讲讲如何在队列中插入和删除数据。
如何判断队列已经满了
| 0 | 1 | 2 | 3 | 4 | front | rear | 新 rear : (rear+1)%MAXSIZE |
|---|---|---|---|---|---|---|---|
| a | 0:a | 1: | (1+1)%5=2 | ||||
| a | b | 0:a | 2: | (2+1)%5=3 | |||
| a | b | c | 0:a | 3: | (3+1)%5=4 | ||
| b | c | d | 1:b | 4: | (4+1)%5=0 | ||
| c | d | e | 2:c | 0: | (0+1)%5=1 | ||
| f | c | d | e | 2:c | 1 | (1+1)%5=2 | |
| f | g | c | d | e | 2:c | 2 | front=rear 所以满栈了 |
利用取模这个思路判断满栈就是
void InsertQueue(struct Queue *q , int e){
if((q->rear+1)% MAXSIZE==q->front){
return;
}
q->base[q->rear]=e;
q->rear = (q->rear+1) % MAXSIZE;
}
我们之前说,队列我们一般使用的是链式存储结构,而不是顺序存储结构。我们今天就看看如何构造队列的顺序存储结构,然后看看顺序存储结构给队列带来了哪些问题。
我们假设,有一个队列

(图片来自于鱼 C 工作室)
入队
我们学习了什么是队列,也了解了队列的一些基本特性,以及如何初始化一个队列,今天我们来看看如何创建和删除以及销毁一个队列。
创建一个队列要注意以下两点
#include <stdio.h>
#include <stdlib.h>
#define sizeof(struct Queue)
struct Queue{
int data;
struct Queue *next;
};
struct Queue_link{
struct Queue *front;
struct Queue *rear;
}
void init(Queue_link *q){
q->frout=q->rear=(struct Queue *)malloc(LEN);
if(!q->front){
exit(0);
}
q->frount->next=NULL;
}