1. 程式人生 > >資料結構-查詢二叉樹

資料結構-查詢二叉樹

查詢二叉樹:始終滿足任一節點的左兒子小於該節點,右兒子大於該節點,

由於其特性,查詢二叉樹的中序遍歷始終為從小到大;

需要注意的是二叉查詢樹的刪除,有2種策略,在刪除節點不多時可以採用懶惰刪除,即標記該節點刪除而非真正的delete,第二種是當刪除節點只有一個兒子或則為葉子節點即沒有兒子時,可直接刪除並將兒子移至該節點,而當刪除節點有左右兒子時將其右子樹最小的節點移動至該節點,當然這裡並非真正的移動而是將目標節點的值賦給他,並刪除目標節點,這裡選用右子樹最小的節點可以保證不破壞查詢二叉樹的特性,

另外需要掌握的是由中序前序推出後序或則由中序後序推前序

/***********************************************
     >  Filename: BST.cpp
     >  Author:   Pyt
     >  Create:   2017-08-04 11:11:03
************************************************/

#include <iostream>
#include <queue>
#include <utility>
using namespace std;

template<typename T>
class BST{
public:
    BST();
    ~BST();
    BST(const BST &t);
    BST& operator=(const BST &t);

    void insert(const T &val);
    void remove(const T &val);
    void clear();
    bool empty() const;
    bool contains(const T &val) const;
    
    void inorder();
    void levelorder() const;

    T findMin() const;
    T findMax() const;

private:
    struct Node{
        T val;
        Node *left;
        Node *right;
        Node(T x, Node *l = NULL, Node *r = NULL) : val(x), left(l), right(r){}
    };
    Node *root;
    
    void insert(const T &val, Node *&t);
    void remove(const T &val, Node *&t);
    void clear(Node *&t);
    bool contains(const T &val, Node *&t) const;

    void inorder(Node *&t) const;
    Node* copy_tree(Node *t);

    Node* findMin(Node *t) const;
    Node* findMax(Node *t) const;
};
/**建構函式****/
template<typename T>
BST<T>::BST()
 : root(NULL)
{

}
/***析構*****/
template<typename T>
BST<T>::~BST()
{
    clear();
}
/***拷貝賦值****/
template<typename T>
BST<T>::BST(const BST &t)
{
    root = copy_tree(t.root);
}
/****賦值過載****/
template<typename T>
BST<T>& BST<T>::operator=(const BST &t)
{
    if(this != &t)
    {
        clear();
        root = copy_tree(t.root);
    }
    return *this;
}
/**插入***/
template<typename T>
void BST<T>::insert(const T &val)
{
    insert(val, root);
}
/***刪除*****/
template<typename T>
void BST<T>::remove(const T &val)
{
    remove(val, root);
}
/****清空查詢樹****/
template<typename T>
void BST<T>::clear()
{
    clear(root);
}
/***判斷樹是否為空***/
template<typename T>
bool BST<T>::empty() const
{
    return root==NULL;
}
/****判斷是否包含某元素****/
template<typename T>
bool BST<T>::contains(const T &val) const
{
    return contains(val, root);
}
/***中序遍歷****/
template<typename T>
void BST<T>::inorder()
{
    inorder(root);
}
/***層序遍歷****/
template<typename T>
void BST<T>::levelorder() const
{
    int curlevel = 0;
    queue<pair<Node*, int>> q;
    if(root)
      q.push(make_pair(root, 0));
    while(!q.empty())
    {
        pair<Node*, int> tmp = q.front();
        q.pop();
        if(tmp.second > curlevel)
        {
            cout << endl;
            curlevel = tmp.second;
        }
        cout << tmp.first->val << " ";
        if(tmp.first->left)
          q.push(make_pair(tmp.first->left, curlevel+1));
        if(tmp.first->right)
          q.push(make_pair(tmp.first->right, curlevel+1));
    }
    cout << endl;
}
/***獲取最小元值****/
template<typename T>
T BST<T>::findMin() const
{
    if(root)
        return findMin(root)->val;
}
/****獲取最大元值****/
template<typename T>
T BST<T>::findMax() const
{
    if(root)
        return findMax(root)->val;
}
/***尋找插入私有函式****/
template<typename T>
void BST<T>::insert(const T &val, Node *&t)
{

    if(t == NULL)
      t = new Node(val);
    if(val < t->val)
      insert(val, t->left);
    else if(val > t->val)
      insert(val, t->right);
}
/****尋找刪除私有函式****/
template<typename T>
void BST<T>::remove(const T &val, Node *&t)
{
    if(t == NULL)
      return ;
    if(val < t->val)
      remove(val, t->left);
    else if(val > t->val)
      remove(val, t->right);
    else
    {
        if(t->left && t->right)
        {
            t->val = findMin(t->right)->val;
            remove(val, t->right);
        }
        else{
            Node *obj = t;
            t = t->left ? t->left : t->right;
            delete obj;
        }
    }
}
/****清空樹私有函式*****/
template<typename T>
void BST<T>::clear(Node *&t)
{
    if(t)
    {
        clear(t->left);
        clear(t->right);
        delete t;
    }
    t = NULL;
}
/***查詢是否包含元素私有函式****/
template<typename T>
bool BST<T>::contains(const T &val, Node *&t) const
{
    if(t == NULL)
      return false;
    else if(val < t->val)
      return contains(val, t->left);
    else if(val > t->val)
      return contains(val, t->right);
    else 
      return true;
}
/***中序遍歷私有函式****/
template<typename T>
void BST<T>::inorder(Node *&t) const
{
    if(t)
    {
        inorder(t->left);
        cout << t->val << " ";
        inorder(t->right);
    }
}
/****深拷貝樹私有函式*****/
template<typename T>
typename BST<T>::Node* BST<T>::copy_tree(Node *t)
{
    if(t == NULL)
      return NULL;
    else
      return new Node(t->val, copy_tree(t->left), copy_tree(t->right));
}
/**找到最小節點私有函式***/
template<typename T>
typename BST<T>::Node* BST<T>::findMin(Node *t) const
{
    if(t->left == NULL)
      return t;
    else
      return findMin(t->left);
}
/***找到最大節點私有函式****/
template<typename T>
typename BST<T>::Node* BST<T>::findMax(Node *t) const
{
    if(t->right == NULL)
      return t;
    else
      return findMax(t->right);
}

int main()
{
    BST<int> a;
    a.insert(8), a.insert(6), a.insert(5), a.insert(7), a.insert(3), a.insert(9), a.insert(7);
    a.levelorder();
    a.remove(6);
    a.levelorder();
    BST<int> b(a);
    b.levelorder();
    BST<int> c;
    c = a;
    c.levelorder();
    c.inorder();
    cout << endl;
    cout << a.findMax() << " " << a.findMin() << endl;
    c.clear();
    cout << c.empty() << endl;
}