复习
栈和队列的概念
- 栈是限定仅在表头进行插入和删除操作的线性表(先进后出)。
- 队列是只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。
树
- 树是一种数据结构,它是由 n ( n ≥ 1 ) n (n\geq1) n(n≥1) 个有限节点组成一个具有层次关系的集合。把它叫做
“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的
特点:
• 每个节点有零个或多个子节点
• 没有父节点的节点称为根节点
• 每一个非根节点有且只有一个父节点;除了根节点外,每个子节点可以分为多个不相交的子
树
• 通过不停的试探去寻找解的一种算法。与其说是一种算法,不如说是一种方法。
• 基础的方法有暴力的搜索法,深搜,广搜三种。
• 更高级的有IDDFS,DBFS,A*,IDA*等等。
1.1、深度优先搜索(dfs)
1.1.1、概念
“一条道走到黑”、 “走不了了再倒回去。”
算法过程:
VOID DFS(状态 A)
- 判断当前的状态是否合法。合法则继续执行,否则则回到上次调用。
- 先下走一层,也就是调用DFS(状态 A + Δ)
1.1.2、例题
1、输出n个数的全排列
1,2,3组成的全排列为:
- 可以写 n 重 for 循环
- 可以用 stl 里面的 next_permutation
递归的来想这个问题,以1,2,3,4为例:
• 如果第一个数固定为1的话
• 后面就跟着2,3,4的全排列—— 所以就相当于是原问题的子问题的求解
• 考虑用递归解决
Void dfs(已经固定了前k-1个数剩下的数的全排列,是哪k-1个数通过标记该数字用没用过
来显示,当前这一步的任务就是把第k个数放上去)
{
如果 已经求出来了 k>n 输出, 返回
否则 i从1到n循环
如果i没有用过,那么就将i固定在当前位置上,并调用 dfs(k+1)
在调用完dfs(k+1)后需要将固定在当前位置上的i拿走
}
void dfs(int dep)
{
if(dep>n)
{
write();
return;
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
a[dep]=i;
dfs(dep+1);
vis[i]=0;
}
}
}
2、输出n个数中选m个的组合
3、N皇后(8皇后的升级版)
在 N ∗ N N * N N∗N 的棋盘上放置 N ( n ≤ 13 ) N(n\leq13)