二叉樹的建立,前中後序遍歷的遞歸版本和非遞歸版本,層序遍歷

首先聲明,此文章的代碼都是整理的大神的代碼。感覺非常好,寫出來當作筆記。

先來看看二叉樹的基本操作:

#include <iostream>
#include <queue>

using namespace std;

template <typename Key, typename Value>
class BST{

private:
    struct Node{
        Key key;
        Value value;
        Node *left;
        Node *right;

        Node(Key key, Value value){
            this->key = key;
            this->value = value;
            this->left = this->right = NULL;
        }
    };

    Node *root;
    int count;

public:
    BST(){
        root = NULL;
        count = 0;
    }
    ~BST(){
        destroy( root );
    }

    int size(){
        return count;
    }

    bool isEmpty(){
        return count == 0;
    }

    void insert(Key key, Value value){
        root = insert(root, key, value);
    }

    bool contain(Key key){
        return contain(root, key);
    }

    Value* search(Key key){
        return search( root , key );
    }

    // 前序遍歷
    void preOrder(){
        preOrder(root);
    }

    // 中序遍歷
    void inOrder(){
        inOrder(root);
    }

    // 後序遍歷
    void postOrder(){
        postOrder(root);
    }

    // 層序遍歷
    void levelOrder(){

        queue<Node*> q;
        q.push(root);
        while( !q.empty() ){

            Node *node = q.front();
            q.pop();

            cout<<node->key<<endl;

            if( node->left )
                q.push( node->left );
            if( node->right )
                q.push( node->right );
        }
    }

private:
    // 向以node爲根的二叉搜索樹中,插入節點(key, value)
    // 返回插入新節點後的二叉搜索樹的根
    Node* insert(Node *node, Key key, Value value){

        if( node == NULL ){
            count ++;
            return new Node(key, value);
        }

        if( key == node->key )
            node->value = value;
        else if( key < node->key )
            node->left = insert( node->left , key, value);
        else    // key > node->key
            node->right = insert( node->right, key, value);

        return node;
    }

    // 查看以node爲根的二叉搜索樹中是否包含鍵值爲key的節點
    bool contain(Node* node, Key key){

        if( node == NULL )
            return false;

        if( key == node->key )
            return true;
        else if( key < node->key )
            return contain( node->left , key );
        else // key > node->key
            return contain( node->right , key );
    }

    // 在以node爲根的二叉搜索樹中查找key所對應的value
    Value* search(Node* node, Key key){

        if( node == NULL )
            return NULL;

        if( key == node->key )
            return &(node->value);
        else if( key < node->key )
            return search( node->left , key );
        else // key > node->key
            return search( node->right, key );
    }

    // 對以node爲根的二叉搜索樹進行前序遍歷
    void preOrder(Node* node){

        if( node != NULL ){
            cout<<node->key<<endl;
            preOrder(node->left);
            preOrder(node->right);
        }
    }

    // 對以node爲根的二叉搜索樹進行中序遍歷
    void inOrder(Node* node){

        if( node != NULL ){
            inOrder(node->left);
            cout<<node->key<<endl;
            inOrder(node->right);
        }
    }

    // 對以node爲根的二叉搜索樹進行後序遍歷
    void postOrder(Node* node){

        if( node != NULL ){
            postOrder(node->left);
            postOrder(node->right);
            cout<<node->key<<endl;
        }
    }

    void destroy(Node* node){

        if( node != NULL ){
            destroy( node->left );
            destroy( node->right );

            delete node;
            count --;
        }
    }
};


int main() {

    srand(time(NULL));
    BST<int,int> bst = BST<int,int>();

    int n = 10;
    for( int i = 0 ; i < n ; i ++ ){
        int key = rand()%n;
        // 爲了後續測試方便,這裏value值取和key值一樣
        int value = key;
        cout<<key<<" ";
        bst.insert(key,value);
    }
    cout<<endl;

    // test size
    cout<<"size: "<<bst.size()<<endl<<endl;

    // test preOrder
    cout<<"preOrder: "<<endl;
    bst.preOrder();
    cout<<endl<<endl;

    // test inOrder
    cout<<"inOrder: "<<endl;
    bst.inOrder();
    cout<<endl<<endl;

    // test postOrder
    cout<<"postOrder: "<<endl;
    bst.postOrder();
    cout<<endl<<endl;

    // test levelOrder
    cout<<"levelOrder: "<<endl;
    bst.levelOrder();
    cout<<endl<<endl;

    return 0;
}



接下來給出非遞歸的版本,課教科書上的實現不太一樣,我覺得教科書上面的實現經典但是理解起來不太容易,這種方式模擬系統棧更加方便的前中後序的變換。

前序遍歷:

#include <iostream>
#include <vector>
#include <stack>
#include <cassert>

using namespace std;

/// 144. Binary Tree Preorder Traversal

/// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

struct Command{
    string s;   // go, print
    TreeNode* node;
    Command(string s, TreeNode* node): s(s), node(node){}
};

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {

        vector<int> res;
        if( root == NULL )
            return res;

        stack<Command> stack;
        stack.push( Command("go", root) );
        while( !stack.empty() ){
            Command command = stack.top();
            stack.pop();

            if( command.s == "print" )
                res.push_back( command.node->val );
            else{
                assert( command.s == "go" );
                if( command.node->right)
                    stack.push( Command("go",command.node->right));
                if( command.node->left)
                    stack.push( Command("go",command.node->left));
                stack.push( Command("print", command.node));
            }
        }
        return res;
    }
};

int main() {

    return 0;
}




中序遍歷:

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

struct Command{
    string s;   // go, print
    TreeNode* node;
    Command(string s, TreeNode* node): s(s), node(node){}
};

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {

        vector<int> res;
        if( root == NULL )
            return res;

        stack<Command> stack;
        stack.push( Command("go", root) );
        while( !stack.empty() ){
            Command command = stack.top();
            stack.pop();

            if( command.s == "print" )
                res.push_back( command.node->val );
            else{
                assert( command.s == "go" );
                if( command.node->right)
                    stack.push( Command("go",command.node->right));
                stack.push( Command("print", command.node));
                if( command.node->left)
                    stack.push( Command("go",command.node->left));
            }
        }
        return res;
    }
};


後序遍歷:


struct Command{
    string s;   // go, print
    TreeNode* node;
    Command(string s, TreeNode* node): s(s), node(node){}
};

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {

        vector<int> res;
        if( root == NULL )
            return res;

        stack<Command> stack;
        stack.push( Command("go", root) );
        while( !stack.empty() ){
            Command command = stack.top();
            stack.pop();

            if( command.s == "print" )
                res.push_back( command.node->val );
            else{
                assert( command.s == "go" );
                stack.push( Command("print", command.node));
                if( command.node->right)
                    stack.push( Command("go",command.node->right));
                if( command.node->left)
                    stack.push( Command("go",command.node->left));
            }
        }
        return res;
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章