基础搜索
搜索的基本算法是:深度优先搜索(DFS, Depth-First Search)、宽度优先搜索(BFS, Breadth-First Search,或称为广度优先搜索)。
静态版二叉树如下
BFS
BFS可以看作是将每一层的节点依次放入队列中
BFS静态二叉树代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct Node{ //静态二叉树
char value;
int lchild, rchild;
}node[maxn];
int index = 0; //记录节点
int newNode(char val){
node[index].value = val;
node[index].lchild = -1; //-1表示空
node[index].rchild = -1;
return index ++;
}
void insert(int &father, int child, int l_r){ //插入孩子
if(l_r == 0) //左孩子
node[father].lchild = child;
else //右孩子
node[father].rchild = child;
}
int buildtree(){ //建一棵二叉树
int A = newNode('A');int B = newNode('B');int C = newNode('C');
int D = newNode('D');int E = newNode('E');int F = newNode('F');
int G = newNode('G');int H = newNode('H');int I = newNode('I');
insert(E,B,0); insert(E,G,1); //E的左孩子是B,右孩子是G
insert(B,A,0); insert(B,D,1);
insert(G,F,0); insert(G,I,1);
insert(D,C,0); insert(I,H,0);
int root = E;
return root;
}
int main(){
int root = buildtree();
queue <int> q;
q.push(root); //从根节点开始
while(q.size()){
int tmp = q.front();
cout << node[tmp].value << " "; //打印队头
q.pop(); //去掉队头
if(node[tmp].lchild != -1) q.push(node[tmp].lchild); //左孩子入队
if(node[tmp].rchild != -1) q.push(node[tmp].rchild); //右孩子入队
}
return 0;
}
DFS
DFS核心就是运用递归的原理实现遍历
DFS静态二叉树代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct Node{
char value;
int lchild, rchild;
}node[maxn];
int index = 0; //记录节点
int newNode(char val){ //新建节点
node[index].value = val;
node[index].lchild = -1; //-1表示空
node[index].rchild = -1;
return index ++;
}
void insert(int &father, int child, int l_r){ //插入孩子
if(l_r == 0) //左孩子
node[father].lchild = child;
else //右孩子
node[father].rchild = child;
}
void preorder (int father){ //求先序序列
if(father != -1){
cout << node[father].value <<" "; //先序输出
preorder (node[father].lchild);
preorder (node[father].rchild);
}
}
void inorder (int father){ //求中序序列
if(father != -1){
inorder (node[father].lchild);;
cout << node[father].value <<" "; //中序输出
inorder (node[father].rchild);
}
}
void postorder (int father){ //求后序序列
if(father != -1){
postorder (node[father].lchild);;
postorder (node[father].rchild);
cout << node[father].value <<" "; //后序输出
}
}
int buildtree(){ //建一棵树
int A = newNode('A');int B = newNode('B');int C = newNode('C');
int D = newNode('D');int E = newNode('E');int F = newNode('F');
int G = newNode('G');int H = newNode('H');int I = newNode('I');
insert(E,B,0); insert(E,G,1); //E的左孩子是B,右孩子是G
insert(B,A,0); insert(B,D,1);
insert(G,F,0); insert(G,I,1);
insert(D,C,0); insert(I,H,0);
int root = E;
return root;
}
int main(){
int root = buildtree();
cout <<"in order: "; inorder(root); cout << endl; //打印中序序列
cout <<"pre order: "; preorder(root); cout << endl; //打印先序序列
cout <<"post order: "; postorder(root); cout << endl; //打印后序序列
return 0;
}
DFS代码框架如下
ans; //答案,用全局变量表示
void dfs(层数,其他参数){
if (出局判断){ //到达最底层,或者满足条件退出
更新答案; //答案一般用全局变量表示
return; //返回到上一层
}
(剪枝) //在进一步DFS之前剪枝
for (枚举下一层可能的情况) //对每一个情况继续DFS
if (used[i] == 0) { //如果状态i没有用过,就可以进入下一层
used[i] = 1; //标记状态i,表示已经用过,在更底层不能再使用
dfs(层数+1,其他参数); //下一层
used[i] = 0; //恢复状态,回溯时,不影响上一层对这个状态的使用
}
return; //返回到上一层
}
DFS的代码比BFS更简单,如果一个问题用BFS和DFS都行,一般用DFS。