二叉樹DFS/BFS實現(C++)

深度優先搜索算法(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章