二叉搜索树

二叉搜索树

二分查找法

通过一个有序的数列快速的查找
查找的数据必须是有序的
#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))
  • 如果只有一个子孩子,直接删除,并指向有节点的孩子
  • 如果要删除的节点左右都有孩子
    1. 找到右子树的最小值 s=min(d->right)
    2. s是d的后继
    3. s.right=del_min(d->right)
    4. s.right=d.left
    5. 删除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();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值