二叉排序树 – ColdCode

一、规定

二叉排序树,也称为双叉搜索树,它是一棵空树;或二叉树具有以下性格:
1. 假定其左树变动从而产生断层空的,左子树上拿杂种的的值缺席其值;
2. 假定右子树变动从而产生断层空的,右子树上拿杂种的的值大于它的值。;
3. 它的摆布子树也辨别出为二叉排序树。

如下图所示:

 二、二叉排序树的C++完成

1、难题规定

为简略起见,在在这点上,将杂种的的键指定典型设置为int。

class BSTNode {
public:
    int key;            //难题的值
    BSTNode* left;      //结的左翼分子
    BSTNode* right;     //杂种的的右亚纲
    BSTNode* parent;    //杂种的父亲/*解释有或起作用*/
    BSTNode(int key, BSTNode* left, BSTNode* right, BSTNode* 父亲) 键(键), 左(左), 右(右), parent(父亲) {}
};

 2、二叉排序树的杂多的作用

class BSTree {
private:
    BSTNode* root;        //根杂种的public:
    /*解释有或起作用*/
    BSTree() 根(空) {};

    /*获取根杂种的*/
    BSTNode* getRoot() {现场恢复 root;}

    /*将键指定键拔出两叉树中*/void insert(int 线索)

    /*将杂种的拔出到两棵树中*/void insert(BSTNode*& root, BSTNode* 杂种的)

    /*先序遍历*/void preOrder(BSTNode* 根)

    /*中序遍历*/void inOrder(BSTNode* 根)

    /*后序遍历*/void postOrder(BSTNode* 根)

    /*运用关键的和现场恢复键指定查找两叉树打中杂种的*/
    BSTNode* search(BSTNode* node, int 线索)

    /*在两叉和现场恢复中找到最小的线索杂种的*/
    BSTNode* minimum(BSTNode* 杂种的)

    /*找到两叉树中最要紧的杂种的并现场恢复*/
    BSTNode* maximum(BSTNode* 杂种的)

    /*查找两叉树杂种的杂种的的以下杂种的*/
    BSTNode* successor(BSTNode* 杂种的)

    /*寻觅两叉树杂种的的前导杂种的*/
    BSTNode* predecessor(BSTNode* 杂种的)

    /*用键的键指定截杂种的*/
    BSTNode* remove(BSTNode*& root, int 线索)

    /*销毁二叉排序树*/void destroy(BSTNode* 根)
};

3、拔出

在二叉排序树停止拔出作用时,每回拔出的难题都是二叉排序树上新的金属薄片难题。可以将难题拔出到一棵早已在的二叉排序树上,也可以经过拔出难题来解释一棵二叉排序树。

/*
* 将杂种的拔出到两棵树中
*
* 决定因素阐明:
*     root 两叉树的根杂种的
*     node 要拔出的杂种的
*/void BSTree::insert(BSTNode*& root, BSTNode* 杂种的)
{
    BSTNode* y = NULL;
    BSTNode* x = root;

    /*找到要拔出的位*/while (x != 空)
    {
        y = x;
        if (杂种的)->key > x->线索)
            x = x->right;
        else x = x->left;
    }

    /*拔出难题*/
    node->parent = y;
    if (y == 空)
        root = node;
    elseif(y->key > node->线索)
        y->left = node;
    else y->right = node;
}

void BSTree::insert(int 线索) {
    BSTNode* node = new BSTNode(key, NULL, NULL, 空);
    拔出(根), 杂种的)
}

4、遍历

二叉排序树的遍历同普通二叉树相等地分为先序、中序、后序遍历,完成缺席辨别。要紧的是要留意,中序遍历二叉排序树会接纳本人线索字的次序序列。

先序遍历

/*先序遍历*/void BSTree::preOrder(BSTNode* 根)
{
    if (根) != 空)
    {
        cout << root->key;
        preOrder(根)->左)
        preOrder(根)->右)
    }
}

中序遍历

中序遍历二叉排序树会接纳本人线索字的次序序列。

/*中序遍历*/void BSTree::inOrder(BSTNode* 根)
{
    if (根) != 空)
    {
        inOrder(根)->左)
        cout << root->key;
        inOrder(根)->右)
    }
}

后序遍历

/*后序遍历*/void BSTree::postOrder(BSTNode* 根)
{
    if (根) != 空)
    {
        postOrder(根)->左)
        postOrder(根)->右)
        cout << root->key;
    }
}

5、查找

当两叉树不为空时,率先,将要找到的键指定与根NO的键指定停止比力。,假定键指定大于根杂种的,过后持续寻觅右子树,要不然查找左子树。反复前述的快跑,直到找到已成现场恢复的杂种的,要不然,现场恢复空。

BSTNode* BSTree::search(BSTNode* node, int 线索)
{
    if (杂种的) == NULL || node->key == 线索)
        return node;
    if (杂种的)->key < 线索)
        search(杂种的)->right, 线索)
    else search(杂种的)->left, 线索)
}

6、山峰与最低的的

在一棵非空二叉排序树中,最小杂种的是最左侧的的贱的杂种的。,最大杂种的是最准确的的杂种的。。

获取最小杂种的

BSTNode* BSTree::minimum(BSTNode* 杂种的)
{
    if (杂种的)->left == 空)
        return node;
    minimum(杂种的)->左)
}

获取最大杂种的

BSTNode* BSTree::maximum(BSTNode* 杂种的)
{
    if (杂种的)->right == 空)
        return node;
    maximum(杂种的)->右)
}

7、征兆杂种的和后续杂种的

杂种的杂种的的前杂种的是拿杂种的中最大的杂种的,就是,杂种的的左子树的最大杂种的。;

杂种的的争吵杂种的是拿具有关键的的杂种的打中最小杂种的。,就是,杂种的的右子树的最小杂种的。。

征兆杂种的

(1)假定杂种的杂种的的左子树变动从而产生断层空的,则左子树的最大难题即为node的征兆杂种的;

(2)假定杂种的杂种的的左子树是空的

  假定杂种的是准确的孩子,则node的征兆杂种的为node的父难题;

  假定杂种的是左翼分子,找到杂种的杂种的的最低的父杂种的,双亲可能有本人合身的的孩子。,此最低的父难题即为node的征兆杂种的。

/*寻觅杂种的杂种的的前辈杂种的*/
BSTNode* BSTree::predecessor(BSTNode* 杂种的)
{
    /*(1)左子树变动从而产生断层空的,现场恢复到左子树的最大杂种的*/if (杂种的)->left != 空)
        return maximum(杂种的)->左)

    /*(2)*/
    BSTNode* 杂种的 = node->parent;
    while (杂种的 != NULL&&node == 杂种的->左)
    {
        node = 杂种的;
        杂种的 = 杂种的->parent;
    }
    return 杂种的;
}

争吵杂种的

(1)假定杂种的杂种的的右子树变动从而产生断层空的,则右子树的最小难题即为node的争吵杂种的;

(2)假定杂种的杂种的的右子树是空的

  假定杂种的是左翼分子,则node的争吵杂种的即为其父难题;

  假定杂种的杂种的是准确的子杂种的,找到杂种的的最低的父杂种的,双亲可能生活孩子,此最低的父难题即为node的争吵杂种的。

/*查找node的争吵杂种的*/
BSTNode* BSTree::successor(BSTNode* 杂种的)
{
    /*(1)右子树变动从而产生断层空的,现场恢复右子树的最低的的杂种的*/if (杂种的)->right != 空)
        return minimum(杂种的)->右)

    /*(2)*/
    BSTNode* 杂种的 = node->parent;
    while (杂种的 != NULL&&node == 杂种的->右)
    {
        node = 杂种的;
        杂种的 = 杂种的->parent;
    }
    return 杂种的;
}

 8、截难题

假定要截的杂种的是*p(p是加标点于要截的杂种的的搀扶),它的父杂种的是*f,非一般性,合用的*p是*f的左亚纲。

(1)假定*p杂种的是叶杂种的,即PL和PR都是空的,只需求修正f>左为空;

(2)假定*p杂种的仅是左子树pL或许只要右子树pR,它只需求创造PL和PR发生F的左翼分子;

(3)假定*p杂种的的左子树和右子树变动从而产生断层空的,截*p后,私有财产其余的元素当中的绝对位稳定,有两种办法可以做到这点:

  ()做法一:带有*sas*p的左子树pL最准确的的杂种的,这么*p p的左子树L*F的左子树,P的右子树pR*S的右子树;

  进行二:*p的坦率地(或坦率地争吵)而变动从而产生断层*p,过后再从二叉排序树中截它的坦率地引座员(或坦率地争吵)。

偶然发现的崇拜者编码(3),采取做法一:

/*获取杂种的的截和现场恢复*/
BSTNode* BSTree::remove(BSTNode*& root, int 线索)
{
    BSTNode* node = search(根), 线索)
    if (杂种的) != 空)
    {
        if (杂种的)->left == NULL && node->right == 空)    //杂种的是叶杂种的
            node = NULL;
        elseif (杂种的)->left == 空)    //杂种的左子树是空的
            node = node->right;
        elseif (杂种的)->right == 空)    //杂种的右子树为空
            node = node->left;
        else//拿杂种的子树都变动从而产生断层空的。        {
            BSTNode* lnode = node->left;    //Lnode是杂种的左子树的根杂种的while (lnode->右)            //找到node左子树最准确的的杂种的估计价值为lnode
                lnode = lnode->right;
            lnode->right = node->right;        //将杂种的的右子树交换成LNG的右子树
            node->right->parent = lnode;
            if (杂种的)->parent->left == 杂种的)    //为杂种的交换杂种的的左子树的位            {
                node->parent->left = node->left;
                node->left->parent = node->parent;
            }
            elseif (杂种的)->parent->right == 杂种的)
            {
                node->parent->right = node->left;
                node->left->parent = node->parent;
            }
        }
    }
    return node;
}

9、销毁

销毁二叉排序树与销毁普通二叉树缺席分别,这是过后遍历方法使遇难的。。

/*两叉树的使遇难*/void BSTree::destroy(BSTNode* 根)
{
    if (根) == 空)
        return;
    destroy(根)->左)
    destroy(根)->右)
    delete root;
}

 三、整个顺序

1、头用纸覆盖

  1 #include 
  2 #include 
  3 #include 
  4usingnamespace std;
  5  6class BSTNode {
  7public:
  8int key;            //难题的值  9     BSTNode* left;        //结的左翼分子 10     BSTNode* right;        //杂种的的右亚纲 11     BSTNode* parent;    //杂种的父亲 12 13/*解释有或起作用*/ 14     BSTNode(int key, BSTNode* left, BSTNode* right, BSTNode* 父亲) 键(键), 左(左), 右(右), parent(父亲) {}
 15};
 16 17class BSTree {
 18private:
 19     BSTNode* root;        //根杂种的 20public:
 21/*解释有或起作用*/ 22    BSTree() 根(空) {};
 23 24/*获取根杂种的*/ 25     BSTNode* getRoot();
 26 27/*将键指定键拔出两叉树中*/ 28void insert(int 线索)
 29 30/*将杂种的拔出到两棵树中*/ 31void insert(BSTNode*& root, BSTNode* 杂种的)
 32 33/*先序遍历*/ 34void preOrder(BSTNode* 根)
 35 36/*中序遍历*/ 37void inOrder(BSTNode* 根)
 38 39/*后序遍历*/ 40void postOrder(BSTNode* 根)
 41 42/*运用关键的和现场恢复键指定查找两叉树打中杂种的*/ 43     BSTNode* search(BSTNode* node, int 线索)
 44 45/*在两叉和现场恢复中找到最小的线索杂种的*/ 46     BSTNode* minimum(BSTNode* 杂种的)
 47 48/*找到两叉树中最要紧的杂种的并现场恢复*/ 49     BSTNode* maximum(BSTNode* 杂种的)
 50 51/*查找两叉树杂种的杂种的的以下杂种的*/ 52     BSTNode* successor(BSTNode* 杂种的)
 53 54/*寻觅两叉树杂种的的前导杂种的*/ 55     BSTNode* predecessor(BSTNode* 杂种的)
 56 57/*用键的键指定截杂种的*/ 58     BSTNode* remove(BSTNode*& root, int 线索)
 59 60/*销毁二叉排序树*/ 61void destroy(BSTNode* 根)
 62};
 63 64 BSTNode* BSTree::getRoot()
 65{
 66return root;
 67}
 68 69/*先序遍历*/ 70void BSTree::preOrder(BSTNode* 根)
 71{
 72if (根) != 空)
 73    {
 74         cout << root->key;
 75         preOrder(根)->左)
 76         preOrder(根)->右)
 77    }
 78}
 79 80/*中序遍历*/ 81void BSTree::inOrder(BSTNode* 根)
 82{
 83if (根) != 空)
 84    {
 85         inOrder(根)->左)
 86         cout << root->key;
 87         inOrder(根)->右)
 88    }
 89}
 90 91/*后序遍历*/ 92void BSTree::postOrder(BSTNode* 根)
 93{
 94if (根) != 空)
 95    {
 96         postOrder(根)->左)
 97         postOrder(根)->右)
 98         cout << root->key;
 99    }
100}
101102 BSTNode* BSTree::search(BSTNode* node, int 线索)
103{
104if (杂种的) == NULL || node->key == 线索)
105return node;
106if (杂种的)->key < 线索)
107         search(杂种的)->right, 线索)
108else search(杂种的)->left, 线索)
109}
110111 BSTNode* BSTree::minimum(BSTNode* 杂种的)
112{
113if (杂种的)->left == 空)
114return node;
115     minimum(杂种的)->左)
116}
117118 BSTNode* BSTree::maximum(BSTNode* 杂种的)
119{
120if (杂种的)->right == 空)
121return node;
122     maximum(杂种的)->右)
123}
124125/*查找node的争吵杂种的*/126 BSTNode* BSTree::successor(BSTNode* 杂种的)
127{
128/*(1)右子树变动从而产生断层空的,现场恢复右子树的最低的的杂种的*/129if (杂种的)->right != 空)
130return minimum(杂种的)->右)
131132/*(2)*/133     BSTNode* 杂种的 = node->parent;
134while (杂种的 != NULL&&node == 杂种的->右)
135    {
136         node = 杂种的;
137         杂种的 = 杂种的->parent;
138    }
139return 杂种的;
140}
141142/*寻觅杂种的杂种的的前辈杂种的*/143 BSTNode* BSTree::predecessor(BSTNode* 杂种的)
144{
145/*(1)左子树变动从而产生断层空的,现场恢复到左子树的最大杂种的*/146if (杂种的)->left != 空)
147return maximum(杂种的)->左)
148149/*(2)*/150     BSTNode* 杂种的 = node->parent;
151while (杂种的 != NULL&&node == 杂种的->左)
152    {
153         node = 杂种的;
154         杂种的 = 杂种的->parent;
155    }
156return 杂种的;
157}
158159/*160* 将杂种的拔出到两棵树中
161*
162* 决定因素阐明:
163*     root 两叉树的根杂种的
164*     node 要拔出的杂种的
165*/166void BSTree::insert(BSTNode*& root, BSTNode* 杂种的)
167{
168     BSTNode* y = NULL;
169     BSTNode* x = root;
170171/*找到要拔出的位*/172while (x != 空)
173    {
174         y = x;
175if (杂种的)->key > x->线索)
176             x = x->right;
177else x = x->left;
178    }
179180/*拔出难题*/181     node->parent = y;
182if (y == 空)
183         root = node;
184elseif(y->key > node->线索)
185         y->left = node;
186else y->right = node;
187}
188189void BSTree::insert(int 线索) {
190     BSTNode* node = new BSTNode(key, NULL, NULL, 空);
191    拔出(根), 杂种的)
192}
193194//BSTNode* BSTree::remove(BSTNode*& root, int 线索)
195//{
196//    BSTNode* x = NULL;
197//    BSTNode* y = NULL;
198//199//    BSTNode* z = search(根), 线索)
200//    if (z->left == NULL || z->right == 空)
201//        y = z;
202//    else y = 继承人(Z)
203//204//    if (y->left != 空)
205//        x = y->left;
206//    else x = y->right;
207//208//    if (x != 空)
209//        x->parent = y->parent;
210//211//    if (y->parent == 空)
212//        root = x;
213//    else if (y->parent->left == y)
214//        y->parent->left = x;
215//    else if (y->parent->right == y)
216//        y->parent->right = x;
217//218//    if (y != z)
219//        z->key = y->key;
220//221//    return y;
222//}223224/*获取杂种的的截和现场恢复*/225 BSTNode* BSTree::remove(BSTNode*& root, int 线索)
226{
227     BSTNode* node = search(根), 线索)
228if (杂种的) != 空)
229    {
230if (杂种的)->left == NULL && node->right == 空)    //杂种的是叶杂种的231             node = NULL;
232elseif (杂种的)->left == 空)    //杂种的左子树是空的233             node = node->right;
234elseif (杂种的)->right == 空)    //杂种的右子树为空235             node = node->left;
236else//拿杂种的子树都变动从而产生断层空的。237        {
238             BSTNode* lnode = node->left;    //Lnode是杂种的左子树的根杂种的239while (lnode->右)            //找到node左子树最准确的的杂种的估计价值为lnode240                 lnode = lnode->right;
241             lnode->right = node->right;        //将杂种的的右子树交换成LNG的右子树242             node->right->parent = lnode;
243if (杂种的)->parent->left == 杂种的)    //为杂种的交换杂种的的左子树的位244            {
245                 node->parent->left = node->left;
246                 node->left->parent = node->parent;
247            }
248elseif (杂种的)->parent->right == 杂种的)
249            {
250                 node->parent->right = node->left;
251                 node->left->parent = node->parent;
252            }
253        }
254    }
255return node;
256}
257258/*两叉树的使遇难*/259void BSTree::destroy(BSTNode* 根)
260{
261if (根) == 空)
262return;
263     destroy(根)->左)
264     destroy(根)->右)
265delete root;
266 }

检查编码

2、检验用纸覆盖bStru.CPP

 1 #include "" 2 3int main()
 4{
 5int a[] = { 1, 5, 4, 3, 2, 6 };
 6 7     BSTree* tree = new BSTree();
 8for (int i = 0; i < 6;i++)
 9         tree->拔出(a)
1011     cout << "先序遍历:";
12     tree->preOrder(tree->getRoot());
13     cout << endl;
1415     cout << "中序遍历:";
16     tree->inOrder(tree->getRoot());
17     cout << endl;
1819     cout << "后序遍历:";
20     tree->postOrder(tree->getRoot());
21     cout << endl;
2223     cout << "最低的的:";
24     BSTNode* minNode = tree->minimum(tree->getRoot());
25if(minNode != 空)
26         cout << minNode->key << endl;
2728     cout << "山峰:";
29     BSTNode* maxNode = tree->maximum(tree->getRoot());
30if (maxNode != 空)
31         cout << maxNode->key << endl;
323334     BSTNode* node = tree->search(tree->getRoot(), 6);
35     BSTNode* snode = tree->successor(杂种的)
36if (SnObl) != 空)
37         cout << snode->key << endl;
3839     BSTNode* 杂种的 = tree->predecessor(杂种的)
40if (杂种的 != 空)
41         cout << 杂种的->key << endl;
4243     BSTNode* root = tree->getRoot();
44     BSTNode* dnode = tree->remove(根), 5);
45     cout << "" << dnode->key << "一阶遍历:" << endl;
46if (d杂种的) delete dnode;
47     tree->preOrder(tree->getRoot());
48     cout << endl;
4950     cout << "两叉树的使遇难" << endl;
51     tree->destroy(根)
52 }

3、卒

先序遍历:154326
中序遍历:123456
后序遍历:234651
最低的的:1
山峰:65
截5一阶遍历:
14326
两叉树的使遇难

四、提及

1、

2、 重度敏感、吴伟文的数据结构

发表评论

电子邮件地址不会被公开。 必填项已用*标注