二叉查找树BST 模板
二叉查找树BST 就是二叉搜索树 二叉排序树。
就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单。
根据BST的性质可以很好的解决这些东西
1.查询值
int Search(int k,int x) { if(x<a[k].key && a[k].l) Search(a[k].l,x); else if(x>a[k].key && a[k].r) Search(a[k].r,x); else return k; }
2.查询最小值最大值
int getmin(int k) { if(!a[k].l)return k; return getmin(a[k].l); } int getmax(int k) { if(!a[k].r)return k; return getmax(a[k].r); }
3.输出排序(其实就是中根遍历)
void Leftorder(int k) { if(a[k].l)Leftorder(a[k].l); printf("%d ",a[k].key); if(a[k].r)Leftorder(a[k].r); }
接下来说一下BST的操作
1.插入
这个没什么好说的,就是小的插右边 大的插左边 递归下去就行了。
void InsertNode(int k,int x) { if(tree_size==0)root=++tree_size,a[root].key=x; else if(x<=a[k].key){ if(a[k].l)InsertNode(a[k].l,x); else{ tree_size++; a[tree_size].key=x; a[tree_size].p=k; a[k].l=tree_size; } } else if(x>a[k].key){ if(a[k].r)InsertNode(a[k].r,x); else{ tree_size++; a[tree_size].key=x; a[tree_size].p=k; a[k].r=tree_size; } } }
2.删除
对于删除点的操作,分下面三种情况:
(1)删的这个点没有左儿子 -> 让它的右子树代替它
(2)删的这个点没有右儿子 -> 让它的左子树代替它
(3)删的这个点子孙齐全 -> 在它的的左子树里选一个最小的(或者在右子树里找一个最大的)放在它的位置,好理解吧
} void Treeplant(int k,int x,int y) //用子树y代替x { if(x==root)root=y; else if(x==a[a[x].p].l)a[a[x].p].l=y; else a[a[x].p].r=y; if(a[y].key)a[y].p=a[x].p; } void DeleteNode(int k,int x) { if(!a[x].l)Treeplant(k,x,a[x].r); //情况一 else if(!a[x].r)Treeplant(k,x,a[x].l); //情况二 else{ //情况三 int y=getmin(a[x].r); if(a[y].p!=x) { Treeplant(1,y,a[y].r); a[y].r=a[x].r,a[a[y].r].p=y; } Treeplant(1,x,y); a[y].l=a[x].l,a[a[y].l].p=y; } }
这点东西都跟算法导论学的 , 很好理解 ,就扯这么多了 ,立个flag明天写Splay