二叉搜索树(BST)

时间:2021-10-15 07:22:03

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

一、算法导论中讲解

1、二叉搜索树

节点

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

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

规则

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

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

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

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

2、二叉搜索树的遍历

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

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

二叉搜索树(BST)

3、查询二叉树

循环查找

二叉搜索树(BST)

迭代查找

二叉搜索树(BST)

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

二叉搜索树(BST)

二叉搜索树(BST)

5、后继和前驱

二叉搜索树(BST)

6、插入

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

二叉搜索树(BST)

伪代码:

二叉搜索树(BST)

7、删除

删除分为三种情况

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

二叉搜索树(BST)                       二叉搜索树(BST)

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

二叉搜索树(BST)

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

二叉搜索树(BST)

伪代码:

节点替换

二叉搜索树(BST)

删除

二叉搜索树(BST)

三、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(),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{,,,,,,};
vector<int> keys2{,,}; shared_ptr<Node> root1;
shared_ptr<Node> root2;
BSTCreat(root1, keys1);
BSTCreat(root2, keys2); cerr << HasSubtree(root1, root2) << endl; return ; }