为了聚焦于二叉搜索树算法的实现,没有采用模板支持不同数据类型,(key, value)均采用 int 数值。
二叉搜索树节点和树定义
// 二叉树节点,(key, value) 为 (int, int)
struct Node {
int key = 0;
int value = 0;
Node *left = nullptr;
Node *right = nullptr;
// Node() : key(0), value(0), left(nullptr), right(nullptr) {}
Node(int k, int v) : key(k), value(v), left(nullptr), right(nullptr) {}
Node(Node *rhs) : key(rhs->key), value(rhs->value), left(rhs->left), right(rhs->right) {}
// Node(int k, int v, Node *left, Node *right) : key(k), value(v), left(left), right(right) {}
};
// 二叉搜索树
class BST {
public:
BST() : root(nullptr), count(0) {}
// BST(Node *p, int size) : root(p), count(size) {}
~BST() { destory(root); }
int size() { return count; }
bool isEmpty() { return count == 0; }
void insert(int k, int v);
Node *search(int k);
bool contain(int k);
// 深度遍历
void preOrder();
void inOrder();
void postOrder();
// 广度遍历
void levelOrder();
// 最大最小值
int maxinum();
int mininum();
void removeMax();
void removeMin();
// 删除任意节点
void removeNode(int key);
// floor/ceil
Node *floor(int key);
Node *ceil(int key);
// 前驱/后继
Node *predecessor(int key);
Node *successor(int key);
private:
void destory(Node *p);
Node *predecessorFromAncestor(Node *p, int key);
Node *successorFromAncestor(Node *p, int key);
Node *floor(Node *p, int key);
Node *ceil(Node *p, int key);
Node *removeNode(Node *p, int key);
Node *maxinum(Node *p);
Node *mininum(Node *p);
Node *removeMax(Node *p);
Node *removeMin(Node *p);
Node *insert(Node *p, int k, int v);
Node *search(Node *p, int k);
bool contain(Node *p, int k);
void preOrder(Node *p);
void inOrder(Node *p);
void postOrder(Node *p);
void levelOrder(Node *p);
Node *root = nullptr;
int count = 0;
};
插入
void BST::insert(int k, int v) {
root = insert(root, k, v);
}
Node *BST::insert(Node *node, int k, int v) {
if (node == nullptr) {
++count; // attention
return new Node(k, v);
}
if (k < node->key) {
node->left = insert(node->left, k, v);
} else if (k > node->key) {
node->right = insert(node->right, k, v);
} else {
node->value = v;
}
return node;
}
查找/是否包含
bool BST::contain(int k) {
return contain(root, k);
}
bool BST::contain(Node *p, int k) {
if (p == nullptr) {
return false;
}
if (k == p->key) {
return true;
} else if (k < p->key) {
return contain(p->left, k);
} else {
return contain(p->right, k);
}
}
Node *BST::search(int k) {
return search(root, k);
}
Node *BST::search(Node *p, int k) {
if (p == nullptr) {
return nullptr;
}
if (k == p->key) {
return p;
} else if (k < p->key) {
return search(p->left, k);
} else {
return search(p->right, k);
}
}
深度遍历(前序、中序、后序遍历)
void BST::preOrder() {
preOrder(root);
}
void BST::inOrder() {
inOrder(root);
}
void BST::postOrder() {
postOrder(root);
}
void BST::preOrder(Node *p) {
if (p) {
std::cout << p->key << "->" << p->value << " ";
preOrder(p->left);
preOrder(p->right);
}
}
void BST::inOrder(Node *p) {
if (p) {
inOrder(p->left);
std::cout << p->key << "->" << p->value << " ";
inOrder(p->right);
}
}
void BST::postOrder(Node *p) {
if (p) {
postOrder(p->left);
postOrder(p->right);
std::cout << p->key << "->" << p->value << " ";
}
}
广度遍历(层序遍历)
void BST::levelOrder() {
levelOrder(root);
}
void BST::levelOrder(Node *p) {
if (!p) {
return;
}
std::queue<Node *> q;
q.push(p);
while (!q.empty()) {
auto node = q.front();
std::cout << node->key << "->" << node->value << " ";
q.pop();
if (node->left) {
q.push(node->left);
}
if (node->right) {
q.push(node->right);
}
}
}
获取最大/最小节点
int BST::maxinum() {
assert(count > 0);
Node *node = maxinum(root);
return node->key;
}
int BST::mininum() {
assert(count > 0);
Node *node = mininum(root);
return node->key;
}
Node *BST::maxinum(Node *p) {
auto node = p;
while (node->right) {
node = node->right;
}
return node;
}
Node *BST::mininum(Node *p) {
auto node = p;
while (node->left) {
node = node->left;
}
return node;
}
删除最大/最小节点
void BST::removeMax() {
if (root) {
root = removeMax(root);
}
}
void BST::removeMin() {
if (root) {
root = removeMin(root);
}
}
Node *BST::removeMax(Node *p) {
// 迭代实现
if (p->right == nullptr) {
// 根节点无右子树
Node *lnode = p->left;
delete p;
return lnode;
}
// 迭代到待删除最小节点
auto p1 = p;
auto p2 = p->right;
while (p2->right) {
p1 = p2;
p2 = p2->right;
}
p1->right = p2->left; // 最大节点可能还有左子节点
delete p2;
--count;
return p;
}
Node *BST::removeMin(Node *p) {
// 迭代实现
if (p->left == nullptr) {
// 根节点无左子树
Node *rnode = p->right;
delete p;
return rnode;
}
// 迭代到待删除最小节点
auto p1 = p;
auto p2 = p->left;
while (p2->left) {
p1 = p2;
p2 = p2->left;
}
p1->left = p2->right; // 最小节点可能还有右子节点
delete p2;
--count;
return p;
}
前驱与后继
// 前驱/后继
Node *BST::predecessor(int key) {
Node *node = search(root, key);
// 如果key所在的节点不存在, 则key没有前驱, 返回NULL
if (node == nullptr) {
return nullptr;
}
// 如果key所在的节点左子树不为空,则其左子树的最大值为key的前驱
if (node->left != nullptr) {
return maxinum(node->left);
}
// 否则, key的前驱在从根节点到key的路径上, 在这个路径上寻找到比key小的最大值, 即为key的前驱,即key所在节点的左、右父母中搜寻
Node *tmpNode = predecessorFromAncestor(root, key);
if (tmpNode != nullptr) {
return tmpNode;
}
return nullptr;
}
Node *BST::predecessorFromAncestor(Node *p, int key) {
if (p->key == key) {
return nullptr;
}
if (key < p->key) {
// 如果当前节点大于key, 则当前节点不可能是比key小的最大值
// 向下搜索到的结果直接返回
return predecessorFromAncestor(p->left, key);
} else {
// 如果当前节点小于key, 则当前节点有可能是比key小的最大值
// 向右继续搜索, 将结果存储到tempNode中
Node *tmpNode = predecessorFromAncestor(p->right, key);
if (tmpNode != nullptr) {
// 如果tempNode为空, 则当前节点即为结果
return tmpNode;
} else {
return p;
}
}
}
Node *BST::successor(int key) {
Node *node = search(root, key);
// 如果key所在的节点不存在, 则key没有前驱, 返回NULL
if (node == nullptr) {
return nullptr;
}
// 如果key所在的节点右子树不为空,则其右子树的最小值为key的后继
if (node->right != nullptr) {
return mininum(node->right);
}
// 否则, key的后继在从根节点到key的路径上, 在这个路径上寻找到比key大的最小值, 即为key的后继,即在key的右父母中搜寻
Node *tmpNode = successorFromAncestor(root, key);
if (tmpNode != nullptr) {
return tmpNode;
}
return nullptr;
}
Node *BST::successorFromAncestor(Node *p, int key) {
if (key == p->key) {
return nullptr;
}
if (p->key < key) {
// 如果当前节点小于key, 则当前节点不可能是比key大的最小值
// 向下搜索到的结果直接返回
return successorFromAncestor(p->right, key);
} else {
// 如果当前节点大于key, 则当前节点有可能是比key大的最小值
// 向左继续搜索, 将结果存储到tempNode中
Node *tmpNode = successorFromAncestor(p->left, key);
if (tmpNode != nullptr) {
return tmpNode;
} else {
// 如果tempNode为空, 则当前节点即为结果
return p;
}
}
}
删除任意节点
// 删除任意节点
void BST::removeNode(int key) {
if (contain(key)) {
root = removeNode(root, key);
}
}
Node *BST::removeNode(Node *p, int key) {
if (key < p->key) {
p->left = removeNode(p->left, key);
return p;
} else if (key > p->key) {
p->right = removeNode(p->right, key);
return p;
} else {
if (p->left == nullptr) {
auto res = p->right;
delete p;
return res;
} else if (p->right == nullptr) {
auto res = p->left;
delete p;
return res;
} else {
auto minNode = mininum(p->right);
Node *newNode = new Node(minNode->key, minNode->value);
newNode->left = p->left;
newNode->right = removeMin(p->right);
return newNode;
}
}
}
floor/ceil
// floor/ceil
int *BST::floor(int key) {
if (count == 0 || key < mininum()) {
return nullptr;
}
Node *node = floor(root, key);
return &(node->key);
}
int *BST::ceil(int key) {
if (count == 0 || key > maxinum()) {
return nullptr;
}
Node *node = ceil(root, key);
return &(node->key);
}
Node *BST::floor(Node *p, int key) {
if (p == nullptr) {
// attention 这儿返回空的含义
return nullptr;
}
// 如果p的key值和要寻找的key值相等
// 则p本身就是key的floor节点
if (p->key == key) {
return p;
}
// 如果p的key值比要寻找的key值大
// 则要寻找的key的floor节点一定在p的左子树中
if (p->key > key) {
return floor(p->left, key);
}
// 如果p->key < key
// 则p有可能是key的floor节点, 也有可能不是(存在比p->key大但是小于key的其余节点)
// 需要尝试向p的右子树寻找一下
Node *res = floor(p->right, key);
if (res != nullptr) {
return res;
}
return p;
}
Node *BST::ceil(Node *p, int key) {
if (p == nullptr) {
// attention 这儿返回空的含义
return nullptr;
}
// 如果p的key值和要寻找的key值相等
// 则p本身就是key的ceil节点
if (p->key == key) {
return p;
}
// 如果p的key值比要寻找的key值小
// 则要寻找的key的ceil节点一定在p的右子树中
if (p->key < key) {
return ceil(p->right, key);
}
// 如果p->key > key
// 则p有可能是key的ceil节点, 也有可能不是(存在比p->key小但是大于key的其余节点)
// 需要尝试向p的左子树寻找一下
Node *res = ceil(p->left, key);
if (res != nullptr) {
return res;
}
return p;
}
销毁节点
void BST::destory(Node *p) {
if (p) {
destory(p->left);
destory(p->right);
delete p;
--count;
}
}
测试
1)前驱、后继测试
// 二叉搜索树前驱后继节点测试
void BSTPreAndSucTest() {
const int N = 1000;
int arr[N];
for (int i = 0; i < N; ++i) {
arr[i] = i;
}
// [0, N-1]的数据打乱后插入二叉搜索树中
std::random_shuffle(arr, arr + N);
BST bst;
for (auto v : arr) {
bst.insert(v, v);
}
for (int i = 1; i < N - 1; ++i) {
assert(bst.predecessor(i)->key == i - 1);
assert(bst.successor(i)->key == i + 1);
}
return;
}
2)floor / ceil测试
// 二叉搜索树 floor / ceil 测试
void BSTFloorAndCeilTest() {
const int N = 1000;
int arr[N];
for (int i = 0; i < N; ++i) {
arr[i] = 2 * i;
}
// [0, 2, 4.... 2*(N-1)]的数据打乱后插入二叉搜索树中
std::random_shuffle(arr, arr + N);
BST bst;
for (auto v : arr) {
bst.insert(v, v);
}
for (int i = 0; i < N - 1; ++i) {
if (i % 2 == 0) {
// 所有偶数在二叉树中存在,则其 floor / ceil 均为其本身
assert(bst.floor(2 * i)->key == 2 * i);
assert(bst.ceil(2 * i)->key == 2 * i);
} else {
// 所有基数在二叉树中不存在,则其 floor / ceil 均为其本身 +1 或者 -1
assert(bst.floor(i)->key == i - 1);
assert(bst.ceil(i)->key == i + 1);
}
}
bst.removeNode(2);
assert(bst.floor(2)->key == 0);
assert(bst.ceil(2)->key == 4);
return;
}
3)其他测试
// 二叉搜索树测试
void BSTTest() {
BST bstree;
// 插入
bstree.insert(5, 50);
bstree.insert(4, 40);
bstree.insert(9, 90);
bstree.insert(1, 10);
bstree.insert(7, 70);
bstree.insert(3, 30);
bstree.insert(6, 60);
bstree.insert(8, 80);
bstree.insert(11, 110);
bstree.insert(10, 100);
// 深度遍历遍历
bstree.preOrder();
std::cout << std::endl;
bstree.inOrder();
std::cout << std::endl;
bstree.postOrder();
std::cout << std::endl;
// 广度遍历
bstree.levelOrder();
std::cout << std::endl;
// 搜索
auto sv = bstree.search(10);
bool cv = bstree.contain(10);
sv = bstree.search(11);
cv = bstree.contain(11);
sv = bstree.search(8);
cv = bstree.contain(8);
sv = bstree.search(13);
cv = bstree.contain(13);
// 最大最小值
int minnum = bstree.mininum();
int maxnum = bstree.maxinum();
// bstree.removeMin();
// bstree.levelOrder();
// std::cout << std::endl;
// bstree.removeMax();
// bstree.levelOrder();
// std::cout << std::endl;
// 删除任意节点
// bstree.removeNode(8);
// bstree.levelOrder();
// std::cout << std::endl;
// bstree.removeNode(1);
// bstree.levelOrder();
// std::cout << std::endl;
// bstree.removeNode(4);
// bstree.levelOrder();
// std::cout << std::endl;
// bstree.removeNode(8);
// bstree.levelOrder();
// std::cout << std::endl;
// bstree.removeNode(9);
// bstree.levelOrder();
// std::cout << std::endl;
// floor/ceil
auto floorv = bstree.floor(4);
floorv = bstree.floor(2);
floorv = bstree.floor(0);
floorv = bstree.floor(3);
auto ceilv = bstree.ceil(5);
ceilv = bstree.ceil(12);
ceilv = bstree.ceil(2);
ceilv = bstree.ceil(3);
ceilv = bstree.ceil(8);
return;
}
参考:
https://blog.csdn.net/weixin_42983849/article/details/105622493