基础搜索学习记录

基础搜索
搜索的基本算法是:深度优先搜索(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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值