深度优先搜索算法(Depth First Search)
DFS是搜索算法的一种。它沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。
如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
如右图所示的二叉树:
A 是第一个访问的,然后顺序是 B、D,然后是 E。接着再是 C、F、G。
那么,怎么样才能来保证这个访问的顺序呢?
分析一下,在遍历了根结点后,就开始遍历左子树,最后才是右子树。
因此可以借助堆栈的数据结构,由于堆栈是后进先出的顺序,由此可以先将右子树压栈,然后再对左子树压栈,
这样一来,左子树结点就存在了栈顶上,因此某结点的左子树能在它的右子树遍历之前被遍历。
广度优先搜索算法(Breadth First Search)
又叫宽度优先搜索,或横向优先搜索。
是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。
如右图所示的二叉树,A 是第一个访问的,然后顺序是 B、C,然后再是 D、E、F、G。
那么,怎样才能来保证这个访问的顺序呢?
借助队列数据结构,由于队列是先进先出的顺序,因此可以先将左子树入队,然后再将右子树入队。
这样一来,左子树结点就存在队头,可以先被访问到。
下面是实现的代码:
#include<iostream> #include <queue> #include<stack> using namespace std; struct Node { int nVal; Node *pLeft; Node *pRight; Node(int val,Node* left=NULL,Node * right=NULL):nVal(val),pLeft(left),pRight(right){}; //构造 }; // 析构 void DestroyTree(Node *pRoot) { if (pRoot==NULL) return; Node* pLeft=pRoot->pLeft; Node* pRight=pRoot->pRight; delete pRoot; pRoot =NULL; DestroyTree(pLeft); DestroyTree(pRight); } // 用queue实现的BFS void BFS(Node *pRoot) { if (pRoot==NULL) return; queue<Node*> Q; Q.push(pRoot); while(!Q.empty()) { Node *node = Q.front(); cout<<node->nVal<<"->"; if (node->pLeft!=NULL) { Q.push(node->pLeft); } if (node->pRight!=NULL) { Q.push(node->pRight); } Q.pop(); } cout<<endl; } // DFS的递归实现 void DFS_Recursive(Node* pRoot) { if (pRoot==NULL) return; cout<<pRoot->nVal<<" "; if (pRoot->pLeft!=NULL) DFS_Recursive(pRoot->pLeft); if (pRoot->pRight!=NULL) DFS_Recursive(pRoot->pRight); } // DFS的迭代实现版本(stack) void DFS_Iterative(Node* pRoot) { if (pRoot==NULL) return; stack<Node*> S; S.push(pRoot); while (!S.empty()) { Node *node=S.top(); cout<<node->nVal<<","; S.pop(); if (node->pRight!=NULL) { S.push(node->pRight); } if (node->pLeft!=NULL) { S.push(node->pLeft); } } } // 打印树的信息 void PrintTree(Node* pRoot) { if (pRoot==NULL) return; cout<<pRoot->nVal<<" "; if (pRoot->pLeft!=NULL) { PrintTree(pRoot->pLeft); } if (pRoot->pRight!=NULL) { PrintTree(pRoot->pRight); } } 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* pRoot = node6; //PrintTree(pRoot); //DFS_Recursive(pRoot); DFS_Iterative(pRoot); DestroyTree(pRoot); return 0; }