二叉搜索树
二分查找法
通过一个有序的数列快速的查找
查找的数据必须是有序的
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
int BinnarySearch(vector<T> arr,int target){
int l=0,r=arr.size()-1;
while(l<=r){
int mid=(r-l)/2+l;
if(arr[mid]==target){
return mid;
}
if(arr[mid] > target){
r=mid-1;
}
else{
l=mid+1;
}
}
return -1;
}
int main(){
vector<int> arr={1,2,3,4,5,6,7,8,9,10};
cout<<arr[BinnarySearch(arr,6)];
return 0;
}
二叉搜索树
优势
高效的插入数据
高效的删除数据
动态的维护数据
实现功能
int min()
int max()
void insert()
void pop_min()
void pop_max()
void at()
数据之间的关系
- 二叉树
- 每个节点的键值大于左孩子
- 每个节点的键值小于右孩子
- 左右孩子为根仍是二叉搜索树
- 不一定是一个完全二叉树
插入实现
- 比根节点大插入到右边
- 比根节点小插入到左边
- 相同的值(是否去重)
- 不去重,插入在左边
树的关系
- 最左边的数据一定是最小值
- 最右边的数据一定是最大值
树的删除
- 时间复杂度O(log(n))
- 如果只有一个子孩子,直接删除,并指向有节点的孩子
- 如果要删除的节点左右都有孩子
- 找到右子树的最小值
s=min(d->right)
- s是d的后继
s.right=del_min(d->right)
s.right=d.left
- 删除d
- 找到右子树的最小值
实现一个二叉搜索树
创建节点
template<class K, class V>
struct Node {
K key;
V val;
Node* left;
Node* right;
Node(K& key, V& val) :key(key), val(val), left(nullptr), right(nullptr) {}
};
创建二叉搜索树
template<class K, class V>
class BST {
int count;
Node<K, V>* root;
public:
BST() {
count = 0;
root = nullptr;
}
~BST() {}
//获取大小
int size() {
return count;
}
//判断是否为空
bool empty() {
return count == 0;
}
//判断是否已存在
bool operator==(K key) {
return contain(root, key);
}
V& operator[](K key) {
Node<K, V>* n = find(root, key);
if (n == nullptr)
throw nullptr;
return n->val;
}
//搜索节点
Node<K, V>* find(Node<K, V>* node, K key) {
if (node == nullptr) {
return nullptr;
}
if (key == node->key) {
return node;
}
if (key < node->key)
return find(node->left, key);
else
return find(node->right, key);
}
bool contain(Node<K, V>* node, K key) {
if (node == nullptr)
return false;
if (node->key == key)
return true;
if (key < node->key)
return contain(node->left, key);
else
return contain(node->right, key);
return true;
}
//插入
void insert(K key, V val) {
root = _insert(root, key, val);
}
Node<K, V>* _insert(Node<K, V>* pair, K key, V val) {
if (pair == nullptr) {
count++;
return new Node<K, V>(key, val);
}
//如果重复,就修改元素value
if (key == pair->key) {
pair->val = val;
return pair;
}
else if (key < pair->key) {
pair->left = _insert(pair->left, key, val);
}
else {
pair->right = _insert(pair->right, key, val);
}
return pair;
}
Node<K, V>* min() {
return min(root);
}
//最小值
Node<K, V>* min(Node<K, V>* node) {
if (node->left == NULL)
return node;
return min(node->left);
}
Node<K, V>* max() {
return max(root);
}
//最大值
Node<K, V>* max(Node<K, V>* node) {
if (node->right == NULL)
return node;
return max(node->right);
}
void pop_min()
{
if (root)
root = pop_min(root);
}
//移除最小值
Node<K, V>* pop_min(Node<K, V>* node) {
if (node->left == nullptr) {
Node<K, V>* temp = node->right;
delete node;
count--;
return temp;
}
node->left = pop_min(node->left);
return node;
}
void pop_max() {
if (root)
{
root = pop_max(root);
}
}
//移除最大值
Node<K, V>* pop_max(Node<K, V>* node) {
if (node->right == nullptr) {
Node<K, V>* temp = node->left;
delete node;
count--;
return temp;
}
node->right = pop_max(node->right);
return node;
}
void out() {
out(root);
}
void out(Node<K, V>* node) {
if (node == nullptr) {
return;
}
cout << node->key << ":" << node->val << endl;
out(node->left);
out(node->right);
}
void remove(K key){
root = remove(root,key);
}
Node<K, V>* remove(Node<K, V>* node,K key){
if(node==nullptr){
return nullptr;
}
if(key<node->key){
node->left =remove(node->left,key);
return node;
}
else if(key>node->key){
node->right =remove(node->right,key);
return node;
}
else{
if(node->left==NULL){
Node<K, V>* temp =node->right;
count--;
delete node;
return temp;
}
if(node->right==NULL){
Node<K, V>* temp =node->left;
count--;
delete node;
return temp;
}
Node<K, V> *temp=min(node->right);
node->key=temp->key;
node->val=temp->val;
node->right=pop_max(node->right);
delete node;
count--;
return node;
}
}
private:
};
测试用例
void test() {
BST<int, char> bst;
bst.insert(10, '1');
bst.insert(20, '2');
bst.insert(30, '3');
bst.insert(40, '4');
cout << bst.size() << endl;
cout << boolalpha << (bst == 30) << endl;
bst[10] = 'A';
cout << bst[10] << endl;
cout << bst[20] << endl;
cout << bst[30] << endl;
cout << bst[40] << endl;
bst.out();
cout << bst.min()->key << endl;
cout << bst.max()->key << endl;
bst.pop_max();
bst.pop_min();
cout << bst.min()->key << endl;
cout << bst.max()->key << endl;
bst.out();
}
int main() {
test();
}