二叉查找树

特征

1.左子树上所有结点的值均小于或等于它的根结点的值

2.右子树上所有结点的值均大于或等于它的根结点的值。

3.左、右子树也分别为二叉排序树。

如下就是一棵典型的二叉查找树

因为查找使用二分查找法,所以查询时间复杂度是 O(lg2)

操作

二叉树的操作也就是增删查、遍历

查找就是二分查找。增添节点和删除节点的时候,要保持二叉树的性质。

遍历分为前序遍历(preorder travel)、中序遍历(inorder travel)、后续遍历(postorder travel)

前序遍历就是根节点第一个被遍历,按照“中左右”顺序,子树也按照这个顺序。中序按照“左中右”顺序。后续按照“左右中”顺序。

可以看到,前序就是根节点第一个被遍历,中序就是根节点在中间被遍历,后续就是根节点最后被遍历。都是针对根节点的。

通过前序+中序、后序+中序 可以还原一棵树。

比如上面这棵树,前序遍历:3102645,中序遍历:0123465

通过前序可以看到3是根节点,再看中序,3前面的 012 就是左子树,3后面的 456 就是右子树。继续看前序,1是左子树的根节点,6是右子树的根节点...依次类推,递归下去。

#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <stack>
#include <list>
#include <queue>
#include <iostream>

enum EColor
{
    WHITE = 0,
    BLACK,
};

template <typename T>
struct stTreeNode
{
    T d;
    int color;
    struct stTreeNode *left, *right;

    stTreeNode(T data):d(data),color(WHITE),left(NULL),right(NULL) {}
};

template <typename T>
class CTree
{
public:
    typedef T               value_type;
    typedef T&              reference;
    typedef T*              pointer;
    typedef stTreeNode<T>   node_type;
    typedef node_type*      node_pointer;

    CTree():root(NULL){}
    CTree(const pointer arr, int len);

    void            insert(value_type data);
    void            del(value_type data);
    node_pointer    find(value_type data);
    bool            empty() {return root == NULL;};

    int             height();

    void            preorderTravel();
    void            inorderTravel();
    void            postorderTravel();
    void            layerTravle();

private:
    node_pointer root;

    void            _insert(node_pointer *root, value_type data);
    int             _height(node_pointer root);
};

template <typename T>
CTree<T>::CTree(const CTree<T>::pointer arr, int len)
{
    root = NULL;
    for (int i = 0; i < len; ++i)
    {
        _insert(&root, arr[i]);
    }
}

template <typename T>
void CTree<T>::_insert(CTree<T>::node_pointer *root, CTree<T>::value_type data)
{
    if (*root == NULL)
    {
        *root = new CTree<T>::node_type(data);
    }
    else if (data > (*root)->d)
    {
        _insert(&(*root)->right, data);
    }
    else
    {
        _insert(&(*root)->left, data);
    }
}

template <typename T>
void CTree<T>::insert(CTree<T>::value_type data)
{
    _insert(&this->root, data);
}

template <typename T>
typename CTree<T>::node_pointer CTree<T>::find(CTree<T>::value_type data)
{
    CTree<T>::node_pointer tmp = root;
    while (tmp != NULL)
    {
        if (tmp->d == data)
        {
            return tmp;
        }
        else if (data > tmp->d)
        {
            tmp = tmp->right;
        }
        else
        {
            tmp = tmp->left;
        }
    }
    return tmp;
}

template <typename T>
void CTree<T>::del(CTree<T>::value_type data)
{
    CTree<T>::node_pointer parent = root;
    CTree<T>::node_pointer tmp = root;
    int left = -1;

    while (tmp != NULL && tmp->d != data)
    {
        parent = tmp;
        if (data > tmp->d)
        {
            tmp = tmp->right;
            left = 0;
        }
        else
        {
            tmp = tmp->left;
            left = 1;
        }
    }

    if (!tmp)
    {
        return;
    }

    // 要删除的节点没有左子树
    if (!tmp->left)
    {
        if (left)
        {
            parent->left = tmp->right;
        }
        else
        {
            parent->right = tmp->right;
        }
    }
    else
    {
        CTree<T>::node_pointer cur = tmp;
        parent = tmp;
        tmp = tmp->left;
        while (tmp->right != NULL)
        {
            parent = tmp;
            tmp = tmp->right;
        }
        cur->d = tmp->d;
        if (parent->left == tmp)
        {
            parent->left = tmp->left;
        }
        else
        {
            parent->right = tmp->left;
        }
        delete tmp;
    }
}

template <typename T>
void CTree<T>::preorderTravel()
{
    std::stack<CTree<T>::node_pointer, std::list<CTree<T>::node_pointer> > S;
    if (root)
    {
        S.push(root);
    }

    while (!S.empty())
    {
        CTree<T>::node_pointer node = S.top();
        std::cout << node->d << " ";
        S.pop();
        if (node->right)
        {
            S.push(node->right);
        }
        if (node->left)
        {
            S.push(node->left);
        }
    }
    std::cout << std::endl;
}

template <typename T>
void CTree<T>::inorderTravel()
{
    std::stack<CTree<T>::node_pointer, std::list<CTree<T>::node_pointer> > S;
    if (root)
    {
        S.push(root);
    }

    while (!S.empty())
    {
        CTree<T>::node_pointer node = S.top();
        if (node->left && node->left->color == WHITE)
        {
            S.push(node->left);
        }
        else
        {
            std::cout << node->d << " ";
            node->color = BLACK;
            S.pop();
            if (node->right)
            {
                S.push(node->right);
            }
        }
    }
    std::cout << std::endl;
}

template <typename T>
void CTree<T>::postorderTravel()
{
    std::stack<CTree<T>::node_pointer, std::list<CTree<T>::node_pointer> > S;
    if (root)
    {
        S.push(root);
    }

    while (!S.empty())
    {
        CTree<T>::node_pointer node = S.top();
        int nextTra = 1;

        if (node->right && node->right->color == WHITE)
        {
            S.push(node->right);
            nextTra = 0;
        }
        if (node->left && node->left->color == WHITE)
        {
            S.push(node->left);
            nextTra = 0;
        }
        if (nextTra)
        {
            std::cout << node->d << " ";
            node->color = BLACK;
            S.pop();
        }
    }
    std::cout << std::endl;
}

template <typename T>
void CTree<T>::layerTravle()
{
    std::queue<CTree<T>::node_pointer, std::list<CTree<T>::node_pointer> > Q;
    if (root)
    {
        Q.push(root);
    }

    while (!Q.empty())
    {
        CTree<T>::node_pointer node = Q.front();
        std::cout << node->d << " ";
        Q.pop();
        if (node->left)
        {
            Q.push(node->left);
        }
        if (node->right)
        {
            Q.push(node->right);
        }
    }
    std::cout << std::endl;
}

template <typename T>
int CTree<T>::_height(CTree<T>::node_pointer root)
{
    if (root == NULL)
    {
        return 0;
    }

    int lh = _height(root->left);
    int rh = _height(root->right);

    return lh > rh ? lh + 1 : rh + 1;
}

template <typename T>
int CTree<T>::height()
{
    return _height(root);
}

int main()
{
    int arr[] = {6,3,4,1,3,8,9,7,6,0,2};
    int len = sizeof(arr)/sizeof(int);
    CTree<int> tree(arr, len);

    tree.preorderTravel();
    tree.postorderTravel();
    tree.layerTravle();

    printf("%d\n", tree.height());

    return 0;
}

 

posted @ 2018-11-06 21:50  二狗啸地  阅读(199)  评论(0编辑  收藏  举报