二叉查找樹的非遞歸操作

昨天同學去參加阿里巴巴面試,被問到二叉樹的一些基本問題,分享一下:

1.如何非遞歸dfs求得樹的深度

2.如何非遞歸bfs求得樹的深度

*3.如何非遞歸地中前後序遍歷二叉查找樹。

二叉樹寫過不下十次了,但是基本每次都是用遞歸來寫,一時間問道還不能一下寫出來。

問題二還是比較好寫,一的話可能需要仔細想想,但是假如是面試的話,可能我一時也說不出來。

老實說,我自己寫得代碼總得看來是滿長的,但是局部核心的是相對比較好理解的。


/***********************************************************
	> OS     : Linux 3.13.0-24-generic (Mint-17)
	> Author : yaolong
	> Mail   : [email protected]
	> Time   : 2014年09月18日 星期四 12時24分57秒
 **********************************************************/
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cstdlib>
using namespace std;
template<typename Comparable>
class BinarySearchTree
{
public:
    BinarySearchTree()
    {
        root = NULL;
    };
    void insert ( Comparable x ) //非遞歸插入
    {
        if ( root == NULL ) //因爲不是傳引用指針
        {
            root = new Node ( x );
        }
        else
        {
            insert ( x, root );
        }
    }
    bool contains ( Comparable x ) //遞歸查詢
    {
        return contains ( x, root );
    }
    void travel_in() //非遞歸中序遍歷
    {
        travel_in ( root );
    }
    void travel_dg_in() //遞歸中序遍歷
    {
        travel_dg_in ( root );
    }
    void travel_pre() //非遞歸前序遍歷
    {
        travel_pre ( root );
    }
    void travel_dg_pre() //遞歸前序遍歷
    {
        travel_dg_pre ( root );
    }
    void travel_suf() //非遞歸後序遍歷,稍微難
    {
        travel_suf ( root );
    }
    void travel_dg_suf() //遞歸後序遍歷
    {
        travel_dg_suf ( root );
    }
    int get_depth_dg() //遞歸搜索樹的深度
    {
        return get_depth_dg ( root );
    }
    int get_depth_dfs() //非遞歸,深度搜索樹的深度
    {
        return get_depth_dfs ( root );
    }
    int get_depth_bfs() //非遞歸,寬度搜索樹得深度
    {
        return get_depth_bfs ( root );
    }


private:
    class Node
    {
    public:
        Comparable element;
        Node *left;
        Node *right;
        Node ( Comparable e , Node *l = NULL, Node *r = NULL ) : element ( e ), left ( l ), right ( r )
        {
        }
    };
    void insert ( Comparable x, Node *p )
    {
        while ( 1 )
        {
            if ( x > p->element ) //比當前節點元素大,插入到右邊
            {
                if ( p->right == NULL )
                {
                    p->right = new Node ( x );
                    return;
                }
                p = p->right;
            }
            else if ( x < p->element )
            {
                if ( p->left == NULL )
                {
                    p->left = new Node ( x );
                    return;
                }
                p = p->left;
            }
            else
            {
                //nothing to do
                return;
            }
        }
    }
    bool contains ( Comparable x, Node *p )
    {
        while ( p != NULL )
        {
            if ( x > p->element )
            {
                p = p->right;
            }
            else if ( x < p->element )
            {
                p = p->left;
            }
            else
            {
                return 1;
            }
        }
        return 0;
    }
    void travel_pre ( Node *p ) //前序遍歷
    {
        stack<Node *> stk;
        while ( p != NULL || !stk.empty() )
        {
            while ( p != NULL ) //先讀,再往左,知道葉子
            {
                cout << p->element << " ";
                stk.push ( p );
                p = p->left;
            }
            if ( !stk.empty() ) //左路訪問完,退回訪問右路,即用右兒子進行繼續遞歸,進行前序遍歷
            {
                p = stk.top();
                stk.pop();
                p = p->right;
            }
        }
    }
    void travel_dg_pre ( Node *p )
    {
        if ( p == NULL )
        {
            return;
        }
        cout << p->element << " ";
        travel_dg_pre ( p->left );
        travel_dg_pre ( p->right );
    }
    void travel_in ( Node *p )
    {
        stack<Node *> stk;
        while ( p != NULL || !stk.empty() )
        {
            while ( p != NULL )
            {
                stk.push ( p );
                p = p->left;
            }
            if ( !stk.empty() )
            {
                p = stk.top();
                stk.pop();
                cout << p->element << " ";
                p = p->right;
            }
        }
    }
    void travel_dg_in ( Node *p )
    {
        if ( p == NULL )
        {
            return;
        }
        travel_dg_in ( p->left );
        cout << p->element << " ";
        travel_dg_in ( p->right );
    }
    void travel_suf ( Node *p )
    {
        stack<Node *> stk;
        Node *prev = NULL;
        while ( p != NULL || !stk.empty() )
        {
            while ( p != NULL )
            {
                stk.push ( p );
                p = p->left;
            }
            p = stk.top();
            if ( p->right == NULL || p->right == prev )
            {
                cout << p->element << " ";
                prev = p;
                stk.pop();
                p = NULL;
            }
            else
            {
                p = p->right;
            }
        }
    }
    void travel_dg_suf ( Node *p )
    {
        if ( p == NULL )
        {
            return;
        }
        travel_dg_suf ( p->left );
        travel_dg_suf ( p->right );
        cout << p->element << " ";
    }
    int get_depth_dfs ( Node *p )
    {
        int depth = 0, d = 0;
        stack<Node *> stk;
        stack<int> stk_depth;
        while ( p != NULL || !stk.empty() )
        {
            while ( p != NULL )
            {
                stk.push ( p );
                stk_depth.push ( d++ );
                p = p->left;
            }
            if ( !stk.empty() )
            {
                d = stk_depth.top();
                depth = max ( d, depth );
                p = stk.top();
                stk.pop();
                stk_depth.pop();
                p = p->right;
                d++;
            }
        }
        return depth;
    }
    int get_depth_bfs ( Node *p )
    {
        queue<Node *> q;
        queue<int> q_d;
        int d = 0;
        int depth = 0;
        q.push ( p );
        q_d.push ( d );
        while ( !q.empty() )
        {
            p = q.front();
            d = q_d.front() ;
            ++d;
            q.pop();
            q_d.pop();
            if ( p->left != NULL )
            {
                q_d.push ( d ) ;
                q.push ( p->left );
                depth = max ( depth, d );
            }
            if ( p->right != NULL )
            {
                q_d.push ( d ) ;
                q.push ( p->right );
                depth = max ( depth, d );
            }
        }
        return depth;
    }
    int get_depth_dg ( Node *p )
    {
        int depth = 0;
        if ( p->left != NULL )
        {
            depth = max ( depth, get_depth_dg ( p->left ) + 1 );
        }
        if ( p->right != NULL )
        {
            depth = max ( depth, get_depth_dg ( p->right ) + 1 );
        }
        return depth;
    }
    Node *root;
};
int main()
{
    BinarySearchTree<int> t;
    for ( int i = 0; i < 100; i++ )
    {
        int tmp = random() % 100000;
        //cout<<tmp;
        t.insert ( tmp );
    }
    cout << "Insert OK" << endl;
    cout << t.contains ( 4 ) << endl;
    cout << t.contains ( 2 ) << endl;
    cout << "非遞歸遞歸前序遍歷:\n";
    t.travel_pre();
    cout << "\n遞歸前序遍歷\n";
    t.travel_dg_pre();
    cout << "\n遞歸中序遍歷\n";
    t.travel_dg_in();
    cout << "\n非遞歸遞歸中序遍歷:\n";
    t.travel_in();
    cout << "\n遞歸後序遍歷\n";
    t.travel_dg_suf();
    cout << "\n非遞歸遞歸後序遍歷:\n";
    t.travel_suf();
    cout << "\n遞歸求的樹的高度\n";
    cout << t.get_depth_dg();
    cout << "\n非遞歸dfs求的樹的高度\n";
    cout << t.get_depth_dfs();
    cout << "\n非遞歸bfs求的樹的高度\n";
    cout << t.get_depth_bfs();
}


發佈了123 篇原創文章 · 獲贊 10 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章