1. 程式人生 > 實用技巧 >C++實現的二叉查詢樹

C++實現的二叉查詢樹

二叉排序樹(Binary Search Tree)又稱二叉排序樹(Binary Sort Tree),或者是一顆空二叉樹,或者是具有一下特性的二叉樹:
  若它的左子樹不為空,則左子樹上的所有結點的值均小於根節點的值。
  若它的右子樹不為空,則右子樹上的所有結點的值均小於根節點的值。
它的左右子樹又分別是二叉排序樹。

結點結構

template<typename T>
//樹結點結構
class BSTNode{
public:
    T _key; //關鍵在字(鍵值)
    BSTNode *_lchild; //左孩
    BSTNode *_rchild; //右孩
    BSTNode *_parent; // 雙親
    
    //建構函式
    BSTNode(T key ,BSTNode *lchild,BSTNode *rchild,BSTNode *parent):
    _key(key),_lchild(lchild),_rchild(rchild),_parent(parent){};
    //使用建構函式初始化表列對以上四個資料進行初始化。
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

二叉查詢樹的操作:

template<typename T>
class BSTree{
private:
    BSTNode<T> *_Root ;  //根結點

public:
    BSTree():_Root(NULL){};
    ~BSTree(){};

    
    void insert (T key);//二叉樹的插入

    BSTNode<T>* search (T key)  ;//二叉樹的查詢
    
    void preOrder()  ;  //先序輸出
    void inOrder() ;   //中序輸出
    void postOrder() ; //後序輸出

    BSTNode<T>* minimumNode();//查詢最小的節點
    BSTNode<T>* maximumNode ();//查詢最大的節點
    
    T minimumKey();//查詢最小的鍵值
    T maximumKey();//查詢最小的鍵值

    void print();//列印二叉樹
    void remove(T key);

    BSTNode<T>* predecessor(BSTNode<T>* x);//查詢某個結點的前驅
    BSTNode<T>* sucessor(BSTNode<T>* x); //查詢某個結點的後繼

    void destory ();

    //內部使用函式,供外部介面呼叫
private:
    void insert(BSTNode<T>* &tree,BSTNode<T>* z);
    BSTNode<T>* search(BSTNode<T>* &tree,T key) const;
    void preOrder(BSTNode<T>*&tree) const;
    void inOrder(BSTNode<T>*&tree) const;
    void postOrder(BSTNode<T>*&tree) const;
    BSTNode<T>* minimumNode(BSTNode<T> *&tree);
    BSTNode<T>* maximumNode (BSTNode<T> *&tree);
    void print(BSTNode<T>*& tree);
    BSTNode<T>* remove(BSTNode<T>* &tree, BSTNode<T> *z);
    void destory(BSTNode<T>*& tree);
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

BSTree類包含了一個BSTNode指標資料成員,代表二叉查詢樹的根結點。類種封裝了二叉查詢樹常用的操作介面,包括:
插入操作:也是建立二叉查詢樹的方法。
遍歷演算法:包括前序、中序、後序(遞迴實現)。
查詢操作:包括查詢某個結點、查詢最小結點、查詢最大結點、查詢最小值、查詢最大值。
刪除操作。
銷燬操作。
列印操作:列印說明二叉樹的結構。
BSTree類大部分的函式都有兩個過載版本,一個僅供類內部使用(privata宣告),另一個則為類使用者使用的公用介面(public宣告)。

前序遍歷:

/*
*
*前序遍歷演算法
*BSTree類內部呼叫函式
*
*/
template<typename T>
void BSTree<T>::preOrder(BSTNode<T>*&tree) const
{
    if(tree)
    {
        cout<<tree->_key<<" ";
        preOrder(tree->_lchild);
        preOrder(tree->_rchild);
    }
}

/*
*介面
*
*/template<typename T>
void BSTree<T>::postOrder()
{
    postOrder(_Root);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

中序遍歷

/*
*
*中序遍歷演算法
*類內部呼叫函式
*
*/
template <typename T>
void BSTree<T>::inOrder(BSTNode<T>*&tree) const
{
    if(tree)
    {
        inOrder(tree->_lchild);
        cout<<tree->_key<<" ";
        inOrder(tree->_rchild);
    }
}

/*
*
*介面
*
*/
template<typename T>
void BSTree<T>::inOrder()
{
    inOrder(_Root);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

後序遍歷

/*
*
*後序遍歷演算法
*類內部呼叫函式
*
*/
template <typename T>
void BSTree<T>::postOrder(BSTNode<T>*&tree) const
{
    if(tree)
    {
        postOrder(tree->_lchild);
        postOrder(tree->_rchild);
        cout<<tree->_key<<" ";
    }
}

/*
*
*介面
*
*/
template<typename T>
void BSTree<T>::postOrder()
{
    postOrder(_Root);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

2.2二叉查詢樹的插入
  構建查詢二叉樹通過二叉查詢樹的插入操作來進行。插入時嚴格按照查詢二叉樹的定義來進行,其插入演算法的基本過程可以分解為:
根結點為空則進行插入。
值比根結點小,在根結點的左子樹進行插入。
值比根結點大,在根節點的右子樹進行插入。
  本文采用非遞迴演算法實現插入操作。

/*
*插入操作
*非遞迴實現
*內部使用函式
*/
template<typename T>
void BSTree<T> ::insert(BSTNode<T>* &tree,BSTNode<T>* z)
{
    BSTNode<T>* parent = NULL;
    BSTNode<T>* temp = tree;

    //尋找插入點
    while(temp!=NULL)
    {
        parent= temp;
        if(z->_key>temp->_key)
            temp= temp->_rchild;
        else 
            temp=temp->_lchild;
    }
    z->_parent = parent;
    if(parent==NULL) //如果樹本來就是空樹,則直接把z節點插入根節點
        tree = z;
    else if(z->_key>parent->_key) //如果z的值大於其雙親,則z為其雙親的右孩
        parent->_rchild = z;
    else                          
        parent->_lchild = z;
}
/*
*
*介面
*/
template <typename T>
void BSTree<T>::insert(T key)
{
    //建立一個新的節點,使用建構函式初始化
    BSTNode<T>* z= new BSTNode<T>(key,NULL,NULL,NULL);
    if(!z) //如果建立失敗則返回
        return ;
    //呼叫內部函式進行插入
    insert(_Root,z);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

2.3 二叉查詢樹的查詢
     2.3.1 查詢某個值的結點
     這裡提供遞迴與非遞迴演算法實現查詢操作。

/*
*查詢操作
*非遞迴實現
*內部使用函式
*/
template <typename T>
BSTNode<T>*  BSTree<T>::search(BSTNode<T>* &tree,T key) const
{
    BSTNode<T>* temp = tree;
    while(temp != NULL)
    {
        if(temp->_key == key)
            return temp;
        else if(temp->_key>key)
            temp = temp->_lchild;
        else
            temp = temp->_rchild;
    }
    return NULL;
}
查詢演算法的遞迴實現
//template<typename T>
//BSTNode<T>* BSTree<T>::search( BSTNode<T>* &tree,T key) const
//{
//    if(!tree)
//    {
//        if(tree->_key==key)
//            return tree;
//        if(tree->_key>key)
//            return search(tree->_lchild,key);
//        if(tree->_key<z->_key)
//            return search(tree->_rchild,key);
//    }
//    return NULL;
//}

/*
*介面
*/
template <typename T>
BSTNode<T> * BSTree<T>::search(T key) 
{
    return search(_Root,key);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

2.3.2查詢二叉查詢樹值最小的結點

/*
*
*查詢最小的結點
*內部呼叫函式
*
*/
template <typename T>
BSTNode<T>* BSTree<T>::minimumNode(BSTNode<T>*&tree)
{
    BSTNode<T>* temp = tree;
    while(temp->_lchild)
    {
        temp= temp->_lchild;
    }
    return temp;
}

/*
*介面
*/
template<typename T>
BSTNode<T>* BSTree<T>::minimumNode()
{
    return minimumNode(_Root);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2.3.3查詢二叉查詢樹中值最大的結點

/*
*
*查詢鍵值最大的節點
*內部呼叫函式
*非遞迴實現
*/
template<typename T>
BSTNode<T>* BSTree<T>::maximumNode(BSTNode<T>* &tree)
{
    BSTNode<T>* temp=tree;
    while(temp->_rchild)
    {
        temp= temp->_rchild;
    }

    return temp;
}

/*
*介面
*/
template<typename T>
BSTNode<T>* BSTree<T>::maximumNode()
{
    return maximumNode(_Root);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

2.3.4查詢二叉查詢樹中最小的值


/*
*
*查詢最小的鍵值
*外部介面函式
*呼叫內部函式minimumNode實現
*/
template<typename T>
T BSTree<T>::minimumKey()
{
    BSTNode<T> *temp = minimumNode(_Root);
    return temp->_key;
}

  2.4.5查詢二叉查詢樹中最大的值


/*
*
*查詢最大的鍵值
*外部介面函式
*呼叫內部函式maximumKey
*/
template<typename T>
T BSTree<T>::maximumKey()
{
    BSTNode<T> *temp = maximumNode(_Root);
    return temp->_key;
}

  2.3列印查詢二叉樹

  該操作把二叉樹中每個結點的父結點、左右孩子結點的資訊描述出來。


/*
*
*列印函式
*打印出平衡二叉樹
*BStree內部函式
*/
template<typename T>
void BSTree<T>::print(BSTNode<T>*& tree)
{
    if(tree) //如果tree不為空
    {
        if(tree->_lchild) //結點有左孩子
        {
            cout<<"節點"<<tree->_key<<"有左孩子為"<<tree->_lchild->_key<<endl;
        }
        else 
            cout<<"節點"<<tree->_key<<"無左孩子"<<endl;
        if(tree->_rchild)
        {
            cout<<"節點"<<tree->_key<<"有右孩子為"<<tree->_rchild->_key<<endl;
        }
        else 
            cout<<"節點"<<tree->_key<<"無右孩子"<<endl;
        print(tree->_lchild);
        print(tree->_rchild);
    }
}

/*
*介面
*/
template<typename T>
void BSTree<T>::print()
{
    print(_Root);
}

  2.4查詢給定結點的前驅結點


/*
*查詢某個節點x的前驅
*
*介面
*
*/

template <typename T>
BSTNode<T>* BSTree<T>::predecessor(BSTNode<T>* x)
{

    //如果x是最小的結點,則它沒有前驅
    if(x->_key == minimumNode(_Root)->_key)
        return NULL;
    
    //否則
    //先獲取二叉樹中鍵值與x的鍵值相同的結點y
    BSTNode <T> * y = NULL;
    y = search(_Root,x->_key);
    if(y==NULL) return NULL;

    //如果y有左孩子,則x的前驅為“以x的左孩為根的子樹的最大結點”
    if(y->_lchild!=NULL)
        return maximumNode(y->_lchild);

    //如果y沒有左孩子,則x有兩種可能:
    //1.y是一個右孩子,此時x的前驅為其雙親節點
    BSTNode<T>* parent = y->_parent;
    if(parent->_rchild == y)
        return parent;

    //2.y是一個左孩子,則其前驅為其雙親結點中“第一個擁有右孩子結點”的結點
    while(parent!=NULL&&parent->_rchild==NULL)
    {
        parent=parent->_parent;
    }
    return parent;
}

  **

## 2.5查詢給定結點的後繼結點

**


/*
*查詢某個節點x的後繼
*
*外部呼叫介面
*
*/
template <typename T>
BSTNode<T>* BSTree<T>::sucessor(BSTNode<T>* x)
{
    //如果x是鍵值最大的,則x沒有後繼結點
    if(x->_key==maximumNode(_Root)->_key)
        return NULL;

    //獲取x在二叉樹中的結點y
    BSTNode<T>* y  = NULL;
    y = search(_Root,x->_key);
    if(!y)              //若二叉樹沒有此結點
        return NULL;

    //如果y有右孩子,則y的後繼為其右孩子的最小結點
    if(y->_rchild!=NULL)
        return minimumNode(y->_rchild);

    //如果y沒有右孩子,則可分為兩種情況:
    //1.y 是左孩子。此時y的後繼為y的父結點
    BSTNode <T>* parent = y->_parent;
    if(y->_parent->_lchild == y)
        return parent;

    //2.y是右孩子。此時y的後繼結點為“第一個擁有左孩且不是y的直接雙親”的結點
    while(parent!=NULL)
    {
        if(parent->_lchild!=NULL&&parent!=y->_parent)
            return parent;
        parent=parent->_parent;
    }
    return NULL;
}

2.6 刪除結點


/*
*
*刪除結點
*BSTree類內部呼叫函式
*
*/
template <class T>
BSTNode<T>* BSTree<T>::remove(BSTNode<T>* &tree, BSTNode<T> *z)
{
    BSTNode<T> *x=NULL;
    BSTNode<T> *y=NULL;

    if ((z->_lchild == NULL) || (z->_rchild == NULL) )
        y = z;
    else
        y = sucessor(z);

    if (y->_lchild != NULL)
        x = y->_lchild;
    else
        x = y->_rchild;

    if (x != NULL)
        x->_parent = y->_parent;

    if (y->_parent == NULL)
        tree = x;
    else if (y == y->_parent->_lchild)
        y->_parent->_lchild = x;
    else
        y->_parent->_rchild= x;

    if (y != z) 
        z->_key = y->_key;

    return y;

}

/*
* 介面
*/
template<typename T>
void BSTree<T>::remove(T key)
{
    BSTNode<T> *z, *node; 
    if ((z = search(_Root, key)) != NULL)
        if ( (node = remove(_Root, z)) != NULL)
            delete node;
}

2.7銷燬二叉查詢樹


/*
*
*銷燬查詢二叉樹
*內部呼叫函式
*
*/
template<typename T>
void BSTree<T>::destory(BSTNode<T>*& tree)
{
    if(tree->_lchild!=NULL)
        destory(tree->_lchild);
    if(tree->_rchild!=NULL)
        destory(tree->_rchild);
    if(tree->_lchild==NULL&&tree->_rchild==NULL)
    {
        delete(tree);
        tree = NULL;
    }
}

/*
*介面
*/
template<typename T>
void BSTree<T>::destory()
{
    destory(_Root);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245

下面是完整原始碼

分為兩個檔案

#ifndef _BINARY_SEARCH_TREE_
#define _BINARY_SEARCH_TREE_
#include <iostream>
using namespace std;
template<typename T>
//樹結點結構
class BSTNode{
public:
    T _key; //關鍵在字(鍵值)
    BSTNode *_lchild; //左孩
    BSTNode *_rchild; //右孩
    BSTNode *_parent; // 雙親
    
    //建構函式
    BSTNode(T key ,BSTNode *lchild,BSTNode *rchild,BSTNode *parent):
    _key(key),_lchild(lchild),_rchild(rchild),_parent(parent){};
};


template<typename T>
class BSTree{
private:
    BSTNode<T> *_Root ;  //根結點

public:
    BSTree():_Root(NULL){};
    ~BSTree(){};

    
    void insert (T key);//二叉樹的插入

    BSTNode<T>* search (T key)  ;//二叉樹的查詢
    
    void preOrder()  ;  //先序輸出
    void inOrder() ;   //中序輸出
    void postOrder() ; //後序輸出

    BSTNode<T>* minimumNode();//查詢最小的節點
    BSTNode<T>* maximumNode ();//查詢最大的節點
    
    T minimumKey();//查詢最小的鍵值
    T maximumKey();//查詢最小的鍵值

    void print();//列印二叉樹
    void remove(T key);

    BSTNode<T>* predecessor(BSTNode<T>* x);//查詢某個結點的前驅
    BSTNode<T>* sucessor(BSTNode<T>* x); //查詢某個結點的後繼

    void destory ();

    //內部使用函式,供外部介面呼叫
private:
    void insert(BSTNode<T>* &tree,BSTNode<T>* z);
    BSTNode<T>* search(BSTNode<T>* &tree,T key) const;
    void preOrder(BSTNode<T>*&tree) const;
    void inOrder(BSTNode<T>*&tree) const;
    void postOrder(BSTNode<T>*&tree) const;
    BSTNode<T>* minimumNode(BSTNode<T> *&tree);
    BSTNode<T>* maximumNode (BSTNode<T> *&tree);
    void print(BSTNode<T>*& tree);
    BSTNode<T>* remove(BSTNode<T>* &tree, BSTNode<T> *z);
    void destory(BSTNode<T>*& tree);
};

/*
*插入操作
*非遞迴實現
*內部使用函式
*/
template<typename T>
void BSTree<T> ::insert(BSTNode<T>* &tree,BSTNode<T>* z)
{
    BSTNode<T>* parent = NULL;
    BSTNode<T>* temp = tree;

    //尋找插入點
    while(temp!=NULL)
    {
        parent= temp;
        if(z->_key>temp->_key)
            temp= temp->_rchild;
        else 
            temp=temp->_lchild;
    }
    z->_parent = parent;
    if(parent==NULL) //如果樹本來就是空樹,則直接把z節點插入根節點
        tree = z;
    else if(z->_key>parent->_key) //如果z的值大於其雙親,則z為其雙親的右孩
        parent->_rchild = z;
    else                          
        parent->_lchild = z;
}
/*
*
*介面
*/
template <typename T>
void BSTree<T>::insert(T key)
{
    //建立一個新的節點,使用建構函式初始化
    BSTNode<T>* z= new BSTNode<T>(key,NULL,NULL,NULL);
    if(!z) //如果建立失敗則返回
        return ;
    //呼叫內部函式進行插入
    insert(_Root,z);
}

/*
*查詢操作
*非遞迴實現
*內部使用函式
*/
template <typename T>
BSTNode<T>*  BSTree<T>::search(BSTNode<T>* &tree,T key) const
{
    BSTNode<T>* temp = tree;
    while(temp != NULL)
    {
        if(temp->_key == key)
            return temp;
        else if(temp->_key>key)d
            temp = temp->_lchild;
        else
            temp = temp->_rchild;
    }
    return NULL;
}
查詢演算法的遞迴實現
//template<typename T>
//BSTNode<T>* BSTree<T>::search( BSTNode<T>* &tree,T key) const
//{
//    if(!tree)
//    {
//        if(tree->_key==key)
//            return tree;
//        if(tree->_key>key)
//            return search(tree->_lchild,key);
//        if(tree->_key<z->_key)
//            return search(tree->_rchild,key);
//    }
//    return NULL;
//}

/*
*介面
*/
template <typename T>
BSTNode<T> * BSTree<T>::search(T key) 
{
    return search(_Root,key);
}
/*
*
*前序遍歷演算法
*外部使用介面
*
*/
template<typename T>
void BSTree<T>::preOrder(BSTNode<T>*&tree) const
{
    if(tree)
    {
        cout<<tree->_key<<" ";
        preOrder(tree->_lchild);
        preOrder(tree->_rchild);
    }
}
template <typename T>
void BSTree<T>::inOrder(BSTNode<T>*&tree) const
{
    if(tree)
    {
        inOrder(tree->_lchild);
        cout<<tree->_key<<" ";
        inOrder(tree->_rchild);
    }
}
template <typename T>
void BSTree<T>::postOrder(BSTNode<T>*&tree) const
{
    if(tree)
    {
        postOrder(tree->_lchild);
        postOrder(tree->_rchild);
        cout<<tree->_key<<" ";
    }
}
/*
*遍歷演算法
*分別為前序、中序、後序
*BSTree 類外部介面函式
*
*/
template<typename T>
void BSTree<T>::preOrder()
{
    preOrder(_Root);
}
template<typename T>
void BSTree<T>::inOrder()
{
    inOrder(_Root);
}
template<typename T>
void BSTree<T>::postOrder()
{
    postOrder(_Root);
}
/*
*
*查詢最小的結點
*內部呼叫函式
*
*/
template <typename T>
BSTNode<T>* BSTree<T>::minimumNode(BSTNode<T>*&tree)
{
    BSTNode<T>* temp = tree;
    while(temp->_lchild)
    {
        temp= temp->_lchild;
    }
    return temp;
}

/*
*介面
*/
template<typename T>
BSTNode<T>* BSTree<T>::minimumNode()
{
    return minimumNode(_Root);
}
/*
*
*查詢鍵值最大的節點
*內部呼叫函式
*非遞迴實現
*/
template<typename T>
BSTNode<T>* BSTree<T>::maximumNode(BSTNode<T>* &tree)
{
    BSTNode<T>* temp=tree;
    while(temp->_rchild)
    {er
        temp= temp->_rchild;
    }

    return temp;
}

/*
*介面
*/
template<typename T>
BSTNode<T>* BSTree<T>::maximumNode()
{
    return maximumNode(_Root);
}
/*
*
*查詢最小的鍵值
*外部介面函式
*呼叫內部函式minimumNode實現
*/
template<typename T>
T BSTree<T>::minimumKey()
{
    BSTNode<T> *temp = minimumNode(_Root);
    return temp->_key;
}
/*
* 
*查詢最大的鍵值
*外部介面函式
*呼叫內部函式maximumKey
*/
template<typename T>
T BSTree<T>::maximumKey()
{
    BSTNode<T> *temp = maximumNode(_Root);
    return temp->_key;
}

/*
*
*列印函式
*打印出平衡二叉樹
*BStree內部函式
*/
template<typename T>
void BSTree<T>::print(BSTNode<T>*& tree)
{
    if(tree) //如果tree不為空
    {
        if(tree->_lchild) //結點有左孩子
        {
            cout<<"節點"<<tree->_key<<"有左孩子為"<<tree->_lchild->_key<<endl;
        }
        else 
            cout<<"節點"<<tree->_key<<"無左孩子"<<endl;
        if(tree->_rchild)
        {
            cout<<"節點"<<tree->_key<<"有右孩子為"<<tree->_rchild->_key<<endl;
        }
        else 
            cout<<"節點"<<tree->_key<<"無右孩子"<<endl;
        print(tree->_lchild);
        print(tree->_rchild);
    }
}

/*
*介面
*/
template<typename T>
void BSTree<T>::print()
{
    print(_Root);
}
/*
*查詢某個節點x的前驅
*
*外部函式呼叫
*
*/

template <typename T>
BSTNode<T>* BSTree<T>::predecessor(BSTNode<T>* x)
{

    //如果x是最小的結點,則它沒有前驅
    if(x->_key == minimumNode(_Root)->_key)
        return NULL;
    
    //否則
    //先獲取二叉樹中鍵值與x的鍵值相同的結點y
    BSTNode <T> * y = NULL;
    y = search(_Root,x->_key);
    if(y==NULL) return NULL;

    //如果y有左孩子,則x的前驅為“以x的左孩為根的子樹的最大結點”
    if(y->_lchild!=NULL)
        return maximumNode(y->_lchild);

    //如果y沒有左孩子,則x有兩種可能:
    //1.y是一個右孩子,此時x的前驅為其雙親節點
    BSTNode<T>* parent = y->_parent;
    if(parent->_rchild == y)
        return parent;

    //2.y是一個左孩子,則其前驅為其雙親結點中“第一個擁有右孩子結點”的結點
    while(parent!=NULL&&parent->_rchild==NULL)
    {
        parent=parent->_parent;
    }
    return parent;
}
/*
*查詢某個節點x的後繼
*
*外部呼叫介面
*
*/
template <typename T>
BSTNode<T>* BSTree<T>::sucessor(BSTNode<T>* x)
{
    //如果x是鍵值最大的,則x沒有後繼結點
    if(x->_key==maximumNode(_Root)->_key)
        return NULL;

    //獲取x在二叉樹中的結點y
    BSTNode<T>* y  = NULL;
    y = search(_Root,x->_key);
    if(!y)              //若二叉樹沒有此結點
        return NULL;

    //如果y有右孩子,則y的後繼為其右孩子的最小結點
    if(y->_rchild!=NULL)
        return minimumNode(y->_rchild);

    //如果y沒有右孩子,則可分為兩種情況:
    //1.y 是左孩子。此時y的後繼為y的父結點
    BSTNode <T>* parent = y->_parent;
    if(y->_parent->_lchild == y)
        return parent;

    //2.y是右孩子。此時y的後繼結點為“第一個擁有左孩且不是y的直接雙親”的結點
    while(parent!=NULL)
    {
        if(parent->_lchild!=NULL&&parent!=y->_parent)
            return parent;
        parent=parent->_parent;
    }
    return NULL;
}
/*
*
*刪除結點
*BSTree類內部呼叫函式
*
*/
template <class T>
BSTNode<T>* BSTree<T>::remove(BSTNode<T>* &tree, BSTNode<T> *z)
{
    BSTNode<T> *x=NULL;
    BSTNode<T> *y=NULL;

    if ((z->_lchild == NULL) || (z->_rchild == NULL) )
        y = z;
    else
        y = sucessor(z);

    if (y->_lchild != NULL)
        x = y->_lchild;
    else
        x = y->_rchild;

    if (x != NULL)
        x->_parent = y->_parent;

    if (y->_parent == NULL)
        tree = x;
    else if (y == y->_parent->_lchild)
        y->_parent->_lchild = x;
    else
        y->_parent->_rchild= x;

    if (y != z) 
        z->_key = y->_key;

    return y;

}

/*
* 介面
*/
template<typename T>
void BSTree<T>::remove(T key)
{
    BSTNode<T> *z, *node; 
    if ((z = search(_Root, key)) != NULL)
        if ( (node = remove(_Root, z)) != NULL)
            delete node;
}
/*
*
*銷燬查詢二叉樹
*內部呼叫函式
*
*/
template<typename T>
void BSTree<T>::destory(BSTNode<T>*& tree)
{
    if(tree->_lchild!=NULL)
        destory(tree->_lchild);
    if(tree->_rchild!=NULL)
        destory(tree->_rchild);
    if(tree->_lchild==NULL&&tree->_rchild==NULL)
    {
        delete(tree);
        tree = NULL;
    }
}

/*
*介面
*/
template<typename T>
void BSTree<T>::destory()
{
    destory(_Root);
}
#endif

BSTree.h

主函式:測試資料

// BSTree.cpp : 定義控制檯應用程式的入口點。
#include "stdafx.h"
#include <iostream>
#include "BSTree.h"
using namespace std;
int main()
{
    BSTree<int> s ;
    int a ;
    cout<<"請輸入二叉樹結點以構造二叉查詢樹:"<<endl;
    while(cin>>a )
        s.insert(a);
    cin.clear();

    cout<<"前序遍歷二叉查詢樹:"<<endl;
    s.postOrder();
    cout<<endl;


    cout<<"中序遍歷二叉查詢樹:"<<endl;
    s.inOrder();
    cout<<endl;


    cout<<"後序遍歷二叉查詢樹:"<<endl;
    s.postOrder();
    cout<<endl;


    cout<<"列印二叉查詢樹"<<endl;
    s.print();

    cout<<"請輸入要查詢的數:"<<endl;

    while(cin>>a)
    {
        BSTNode<int>* findnode = s.search(a);
        if(!findnode)
        {
            cout<<"查詢失敗"<<endl;
            s.insert(a);
            cout<<"已經將"<<a<<"插入二叉查詢樹,現在二叉查詢樹為:"<<endl;
            s.inOrder();
            cout<<endl;
        }
        else
        {
            cout<<findnode->_key<<"查詢成功"<<endl;
        }
    }
    cin.clear();

    cout<<"請輸入結點以查詢其前驅節點"<<endl;
    BSTNode<int>* findPreNode= new BSTNode<int>(1,NULL,NULL,NULL);
    while(cin>>findPreNode->_key)
    {
        BSTNode<int>* preNode ;
        if((preNode= s.predecessor(findPreNode))!=NULL)
        {
            cout<<"其前驅結點為:";
            cout<<preNode->_key<<endl;
        }
        else 
            cout<<"沒有前驅結點"<<endl;

        if((preNode= s.sucessor(findPreNode))!=NULL)
        {
            cout<<"其後繼結點為:";
            cout<<preNode->_key<<endl;
        }
        else 
            cout<<"沒有後繼結點"<<endl;
    }

    cin.clear();
    cout<<"請輸入要刪除的結點:"<<endl;
    while(cin >>a)
    {

        s.remove(a);
        cout<<"刪除後的二叉排序樹:"<<endl;
        s.inOrder();
    }


    BSTNode<int>* maxNode =  s.minimumNode();
    if(!maxNode)
        cout<<"最小的節點為:"<<maxNode->_key<<endl;

    BSTNode<int>* minNode = s.maximumNode();
    if(!minNode)
        cout<<"最大的節點為:"<<minNode->_key<<endl;

    cout<<"銷燬二叉樹"<<endl;
    s.destory();
    s.inOrder();

    system("pause");

    return 0;
}