---
tags: codebook
---
{%hackmd theme-dark %}
# Binary search tree
## 概念
1. 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值
2. 若任意節點的右子樹不空,則右子樹上所有節點的值均大於或等於它的根節點的值
3. 任意節點的左、右子樹也分別為二元搜尋樹
## 範例
```graphviz
digraph tree{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
8 -> {3 10}
3 -> {1 6}
6 -> {4 7}
10 -> {tmp1[label=nul] 14}
14 -> {tmp2[label=nul] 13}
1->{tmp3[label=nul] tmp4[label=nul]}
4->{tmp5[label=nul] tmp6[label=nul]}
7->{tmp7[label=nul] tmp8[label=nul]}
13->{tmp10[label=nul] tmp9[label=nul]}
}
```
```cpp=
#include<iostream>
#include<vector>
#include<random>
#include<numeric>
#include<utility>
#include<ctime>
using namespace std;
```
```cpp=
mt19937 rd;
template<typename T>
struct bst{
struct node{
using nptr=node*;
T v; nptr l,r;
node(const T& x):v(x){l=r=nullptr;}
} *root;
using nptr=node*;
void print(ostream& os,nptr cur){
if(!cur) return;
print(os,cur->l);
os<<cur->v<<' ';
print(os,cur->r);
}
void print(ostream& os){print(os,root);}
nptr merge(nptr a,nptr b){
if(!a) return b;
if(!b) return a;
if(rd()&1){
a->r=merge(a->r,b);return a;
}else{
b->l=merge(a,b->l);return b;}
}
bst merge(bst b){
root=merge(root,b.root);return *this;
}
void split(nptr cur,const T& x,nptr& a,nptr& b){
if(!cur){a=b=nullptr;return;}
if(cur->v<x)
a=cur,split(a->r,x,a->r,b);
else
b=cur,split(b->l,x,a,b->l);
}
auto split(const T& x){
bst a,b;
split(root,x,a.root,b.root);
return make_pair(a,b);
}
void insert(const T& x,nptr& cur){
if(!cur) cur=new node(x);
else if(cur->v==x) return;
else insert(x,(x<cur->v?cur->l:cur->r));
}
void insert(const T& x){insert(x,root);}
void erase_r(nptr& rt,nptr& cur){
if(!cur) rt=rt->l;
else if(cur->l) erase_r(rt,cur->l);
else rt->v=cur->v,cur=cur->r;
}
void erase(const T& x,nptr& cur){
if(!cur) return;
if(cur->v==x) erase_r(cur,cur->r);
else erase(x,(x<cur->v?cur->l:cur->r));
}
void erase(const T& x){erase(x,root);}
bool count(const T& x,node* cur){
if(!cur) return false;
else if(cur->v==x) return true;
else return count(x,(x<cur->v?cur->l:cur->r));
}
bool count(const T& x){return count(x,root);}
bst(const vector<T>& v={}):root(nullptr){
for(const auto& i:v) insert(i);
}
};
ostream& operator<<(ostream& os,const vector<T>& v){
for(const auto& i:v) os<<i <<' ';
return os;
}
ostream& operator<<(ostream& os,bst t){
t.print(os);return os;
}
```