二分查找树(BST)的实现-查找、插入、删除操作

注:

一、此案例的删除操作

①使用递归函数

②优先减少高度更高的子树,涉及中序前驱(inorder predecessor)中序后继(inorder successor)。

二、树的节点包含key与value,value为泛型。

BST.h

#pragma once
#include <iostream>
using namespace std;
template<typename T>
struct Node
{
	Node<T>* rchild = nullptr;
	Node<T>* lchild = nullptr;
	int key = 0;
	T value = 0;
};


template<typename T>
class BST
{
private:
	Node<T>* root = nullptr;
	Node<T>* find_node(int key);
	void clear(Node<T>* node);
public:
	~BST();
	T find(int key);
	int height(Node<T>* root);

	void insert(int key, T value);

	void delete_(int key);
	Node<T>* recursive_del(Node<T>* root, int key);


	Node<T>* inorder_successor(Node<T>* node);
	Node<T>* inorder_predecessor(Node<T>* node);

	void preorder_traversal();
	void preorder_traversal(Node<T>* node);

	void inorder_traversal();
	void inorder_traversal(Node<T>* node);
};

template<typename T>
inline Node<T>* BST<T>::find_node(int key)
{
	Node<T>* p = root;
	while (p != nullptr) {
		if (key > p->key)
			p = p->rchild;
		else if (key < p->key)
			p = p->lchild;
		else
			return p;
	}
	return nullptr;
}

template<typename T>
inline void BST<T>::clear(Node<T>* node)
{
	if (node == nullptr) return;
	clear(node->lchild);
	clear(node->rchild);
	delete node;
}
template<typename T>
inline BST<T>::~BST()
{
	clear(root);
}

template<typename T>
inline T BST<T>::find(int key)
{
	Node<T>* p = find_node(key);
	if (p != nullptr) return p->value;
	else return 0;
}

template<typename T>
inline int BST<T>::height(Node<T>* root)
{
	if (root == nullptr) return 0;
	int x, y;
	x = height(root->lchild);
	y = height(root->rchild);
	return x > y ? x + 1 : y + 1;
}

template<typename T>
inline void BST<T>::insert(int key, T value)
{
	if (root == nullptr) {
		root = new Node<T>;
		root->value = value;
		root->key = key;
		return;
	}

	Node<T>* p = root;
	Node<T>* q = nullptr;
	while (p != nullptr) {
		q = p;
		if (key > p->key)
			p = p->rchild;
		else if (key < p->key)
			p = p->lchild;
		else {
			q = p;
			break;
		}
	}
	if (q == p) return;
	Node<T>* new_node = new Node<T>;
	new_node->value = value;
	new_node->key = key;

	if (q->key < key) q->rchild = new_node;
	else q->lchild = new_node;

	
	
}

template<typename T>
inline void BST<T>::delete_(int key)
{
	recursive_del(root, key);
}

template<typename T>
inline Node<T>* BST<T>::recursive_del(Node<T>* root, int key)
{
	if (root == nullptr) return nullptr;
	if (root->lchild == nullptr && root->rchild == nullptr) {
		if (root == this->root) this->root = nullptr;
		delete root;
		return nullptr;
	}

	if (key < root->key) 
		root->lchild = recursive_del(root->lchild, key);
	else if (key > root->key) 
		root->rchild = recursive_del(root->rchild, key);
	else {
		if (height(root->lchild) > height(root->rchild)) {
			Node<T>* p = inorder_predecessor(root);
			root->key = p->key;
			root->value = p->value;
			root->lchild = recursive_del(root->lchild, p->key);
		}
		else {
			Node<T>* p = inorder_successor(root);
			root->key = p->key;
			root->value = p->value;
			root->rchild = recursive_del(root->rchild, p->key);
		}
	}
	return root;
}


template<typename T>
inline Node<T>* BST<T>::inorder_successor(Node<T>* node)
{
	if (node->rchild == nullptr) return nullptr;

	Node<T>* p = node->rchild;
	Node<T>* q = nullptr;
	while (p != nullptr) {
		q = p;
		p = p->lchild;
	}
	return q;
}

template<typename T>
inline Node<T>* BST<T>::inorder_predecessor(Node<T>* node)
{
	if (node->lchild == nullptr) return nullptr;
	
	Node<T>* p = node->lchild;
	Node<T>* q = nullptr;
	while (p != nullptr) {
		q = p;
		p = p->rchild;
	}
	return q;
}

template<typename T>
inline void BST<T>::preorder_traversal()
{
	cout << "preorder traversal:" << endl;
	preorder_traversal(root);
}

template<typename T>
inline void BST<T>::preorder_traversal(Node<T>* node)
{
	if (node != nullptr) {
		cout << "(" << node->value << ", " << node->key << ")" << endl;
		preorder_traversal(node->lchild);
		preorder_traversal(node->rchild);
	}
}

template<typename T>
inline void BST<T>::inorder_traversal()
{
	cout << "inorder traversal:" << endl;
	inorder_traversal(root);
}

template<typename T>
inline void BST<T>::inorder_traversal(Node<T>* node)
{
	if (node != nullptr) {
		inorder_traversal(node->lchild);
		cout << "(" << node->value << ", " << node->key << ")" << endl;
		inorder_traversal(node->rchild);
	}
}

Main function

#include <iostream>
#include "BST.h"
using namespace std;

int main()
{
    BST<int> bst;

    bst.insert(10, 10);
    bst.insert(11, 11);
    bst.insert(5, 5);
    bst.insert(12, 12);
    bst.insert(1, 1);
    bst.insert(7, 7);
    bst.insert(6, 6);
    bst.insert(8, 8);
    bst.insert(2, 2);
    bst.insert(3, 3);

    bst.preorder_traversal();
    bst.inorder_traversal();

    bst.delete_(5);
    bst.preorder_traversal();
    bst.inorder_traversal();

    bst.insert(5, 5);
    bst.preorder_traversal();
    bst.inorder_traversal();
}

最初生成的树

输出结果:

preorder traversal:
(10, 10)
(5, 5)
(1, 1)
(2, 2)
(3, 3)
(7, 7)
(6, 6)
(8, 8)
(11, 11)
(12, 12)
inorder traversal:
(1, 1)
(2, 2)
(3, 3)
(5, 5)
(6, 6)
(7, 7)
(8, 8)
(10, 10)
(11, 11)
(12, 12)
preorder traversal:
(10, 10)
(3, 3)
(1, 1)
(2, 2)
(7, 7)
(6, 6)
(8, 8)
(11, 11)
(12, 12)
inorder traversal:
(1, 1)
(2, 2)
(3, 3)
(6, 6)
(7, 7)
(8, 8)
(10, 10)
(11, 11)
(12, 12)
preorder traversal:
(10, 10)
(3, 3)
(1, 1)
(2, 2)
(7, 7)
(6, 6)
(5, 5)
(8, 8)
(11, 11)
(12, 12)
inorder traversal:
(1, 1)
(2, 2)
(3, 3)
(5, 5)
(6, 6)
(7, 7)
(8, 8)
(10, 10)
(11, 11)
(12, 12)

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值