二叉搜索树(BST)

(第一段日常扯蛋,大家不要看)这几天就要回家了,osgearth暂时也不想弄了,毕竟不是几天就能弄出来的,所以打算过完年回来再弄。这几天闲着也是闲着,就掏出了之前买的算法导论看了看,把二叉搜索树实现了下。

一、算法导论中讲解

1、二叉搜索树

节点

每个节点包含key(关键字)、left(指向左孩子)、right(指向右孩子)、parent(指向父节点)。

额外可有可无num(相同关键字的节点个数)。

规则

整个二叉树的根节点的parent指向NULL,且唯一。

左子树上所有节点的key均小于其根节点的key。

右子树上所有节点的key均大于其根节点的key。

最低层的节点的left与right指向NULL。

2、二叉搜索树的遍历

二叉搜索树的遍历分为先序遍历,中序遍历,后序遍历(由x.key的输出位置决定)。

中序遍历即为按照key从大到小输出。

3、查询二叉树

循环查找

迭代查找

4、最大关键字元素和最小关键字元素

5、后继和前驱

6、插入

对于BST插入只能插入到最下层,例如插入13。

伪代码:

7、删除

删除分为三种情况

  1.删除节点的left(或者right)指向NULL,直接把right(或者left)提升到该节点处。

                      

  2.删除节点的right和left不为NULL,且其right的left为NULL,直接把right提升到该节点处。

  3.删除节点的right和left不为NULL,且其right的left不为NULL,找到删除节点的后继(即大于删除节点key的最小key所在节点y),把后继y的right提到后继y的位置(即让后继y的parent的left指向后继y的right),再用删除节点的right和left分别代替后继y的right和left,最后再用后继y把删除节点替换掉。

伪代码:

节点替换

删除

三、c++代码

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

//节点结构
struct Node {
    int key;
    int num;
    shared_ptr<Node> parent;
    shared_ptr<Node> left;
    shared_ptr<Node> right;
    Node(int _key) : key(_key), num(1),parent(NULL), left(NULL), right(NULL) {}
};

//循环插入
bool Insert(shared_ptr<Node>& root, int _key) {
    shared_ptr<Node> node(new Node(_key));
    if (root == NULL) {
        root = node;
        return true;
    }
    shared_ptr<Node> x = root;
    shared_ptr<Node> y;
    while(x != NULL) {
        y = x;
        if (node->key == x->key) {
            x->num++;
            return true;
        }
        if (node->key < x->key) x = x->left;
        else x = x->right;
    }
    if (node->key < y->key) {
        y->left = node;
        node->parent = y;
    }
    else {
        y->right = node;
        node->parent = y;
    }
    return true;
}

//迭代插入
bool reInsert(shared_ptr<Node>& root, shared_ptr<Node> node) {
    if (root == NULL) {
        root = node;
        return true;
    }
    if (node->key == root->key) {
        root->num++;
        return true;
    }
    if (node->key < root->key) return reInsert(root->left, node);
    else return reInsert(root->right, node);
}

//创建二叉树
void BSTCreat(shared_ptr<Node>& root, vector<int> keys) {
    for (int key : keys) {
        Insert(root, key);
    }
}

//遍历
void showBST(shared_ptr<Node>& root) {
    if (root != NULL) {
//     //cout << root->key << " ";//先序遍历
//        showBST(root->left);
//        cout << root->key << " "; //中序遍历
//        showBST(root->right);
//     //cout << root->key << " ";//后序遍历
        //cout << root->key << " "; //first
        showBST(root->left);
        cout << root->key << " "; //mid
        showBST(root->right);
        //cout << root->key << " "; //end
    }
}

//删除节点
bool Delete(shared_ptr<Node>& root, int _key) {
    if(root == NULL) return false;
    if(root->key < _key) return Delete(root->right, _key);
    else if(root->key > _key)return Delete(root->left, _key);
    else {
        if (root->right==NULL) {
            root = root->left;
            return true;
        }
        if (root->left==NULL) {
            root = root->right;
            return true;
        }
        if (root->right->left==NULL) {
            root->right->left = root->left;
            root = root->right;
            return true;
        }
        shared_ptr<Node> y = root->right;
        while(y->left!=NULL) {
            y = y->left;
        }
        y->parent->left = y->right;
        y->right = root->right;
        y->left = root->left;
        root = y;
        return true;
    }
}

bool isSubtree(shared_ptr<Node> pRootA, shared_ptr<Node> pRootB) {
    if (pRootB == NULL) return true;
    if (pRootA == NULL) return false;
    if (pRootB->key == pRootA->key) {
        return isSubtree(pRootA->left, pRootB->left)
                && isSubtree(pRootA->right, pRootB->right);
    } else return false;
}

bool HasSubtree(shared_ptr<Node> pRootA, shared_ptr<Node> pRootB)
{
    if (pRootA == NULL || pRootB == NULL) return false;
    return isSubtree(pRootA, pRootB) ||
            HasSubtree(pRootA->left, pRootB) ||
            HasSubtree(pRootA->right, pRootB);
}

int main() {
    vector<int> keys1{1,2,3,4,5,6,7};
    vector<int> keys2{3,4,5};

    shared_ptr<Node> root1;
    shared_ptr<Node> root2;
    BSTCreat(root1, keys1);
    BSTCreat(root2, keys2);

    cerr << HasSubtree(root1, root2) << endl;

    return 0;

}
原文地址:https://www.cnblogs.com/narjaja/p/8405972.html