上一篇文章整理了一下二叉树的BFS,很重要的哦。那这一篇文章就来点更重要的东西吧——DFS,和BFS是不是兄弟啊!
我们先来个铺垫,如何遍历二叉树?上一篇文章给了一个答案,BFS是按照层来遍历,“ 如果你愿意一层一层一层的剥开我的心”咳咳~~23333,哈!对!就像洋葱,一层层地遍历。那还有其他的遍历方式吗?当然还有,就是递归遍历。
DFS—深度优先遍历
二叉树的深度优先遍历方式有三个:
-先序遍历
PreOrder(T) = T的根结点+PreOrder(T的左子树)+PreOrder(T的右子树)
-中序遍历
InOrder(T) = InOrder(T的左子树)+ T的根结点 + InOrder(T的右子树)
-后序遍历
PostOrder(T) =PostOrder(T的左子树)+ PostOrder(T的右子树)+ T的根结点
可见这些遍历的方式都运用了递归的方式。
树的DFS的思想就是:从根结点开始一直往子树转移,转移到叶子后没有状态可以转移的时候,就回退到前一步的根结点状态继续转移到其他状态,如此重复。
1
2 3
4 5 6 7
用这个图来模拟一下遍历过程:
1.先序遍历:1->2->4->5->3->6->7
2.中序遍历:4->2->5->1->6->3->7
3.后序遍历:4->5->2->6->7->3->1
如何实现DFS
答:递归。当然,有人说用栈来实现也是一样意思的,本来递归的过程就是入栈出栈的过程嘛!
递归实现过程代码(先序):
#include<cstdio>
#include<vector>
using namespace std;
struct Node{
int v;
Node *left,*right;
Node(int v,Node *left=NULL,Node *right=NULL):v(v),left(left),right(right){}
};
void dfs(Node* root,vector<int>& ans)//用vector来保存遍历的结点
{
if(root==NULL) return;//如果为空则返回
Node* u = root;
ans.push_back(u->v);//将结点值插入到vector ans中
if(u->left!=NULL) dfs(u->left,ans);//如果左子结点不为空,则递归到左子结点,一直一直递归然后左子结点为空
if(u->right!=NULL) dfs(u->right,ans);//同理
}
int main()
{
Node* node1=new Node(4);
Node* node2=new Node(5);
Node* node3=new Node(6);
Node* node4=new Node(2,node1,node2);
Node* node5=new Node(3,node3);
Node* node6=new Node(1,node4,node5);//建立一棵二叉数
Node* root = node6;//根结点为node6
vector<int>v;
dfs(root,v);//从根结点开始深度遍历
for(int i=0;i<v.size();i++)
{
printf("%d ",v[i]);
}
return 0;
}
ok,这就是DFS的思想。