二叉查找树是类似于一种堆的数据结构(没有重复元素)
二叉查找有一个性质:中序遍历得到的就是关键码升序排列的序列
这个结构支持很多的操作
- insert(int val):新增一个关键码为val的节点
- get(int val):查找关键码为val的节点
- getnext(int val):查找val的前驱(严格大于val的最小值,可能vall不在树中)
- getpre(int val):查找val的后继(严格小于val的最大值,可能val不在树中)
- remove(int val):删除关键码为val的节点
- getrank(int val):查找val的排名
- getkth(int k):查找排名为k的val
定义一个二叉查找树
struct node{ ll l,r,val; }tree[100010]; ll tot,root; ll newnode(ll val){//新建一个节点 tree[++tot].val=val; return tot; }void build(){//初始化,建树 newnode(~0x3f3f3f3f); newnode(0x3f3f3f3f); root=1; tree[1].r=2; }
查找关键码为val的节点
//在以tree[p]为根的子树中查找val,主函数调用get(root,val); ll get(ll p,ll val){//节点编号,关键码 if(p==0) return 0; if(tree[p].val==val) return p; else if(tree[p].val>val) return get(tree[p].l,val); else return get(tree[p].r,val); }
新增一个关键码为val的节点
//在以tree[p]为根的子树中查入val,主函数调用insert(root,val); void insert(ll & p,ll val){ if(p==0) { p=newnode(val); return ; } if(tree[p].val==val) return ; else if(tree[p].val>val) insert(tree[p].l,val); else insert(tree[p].r,val); }
查找最小和最大的节点
ll getmin(ll p){ if(tree[p].l==0) return p; return getmin(tree[p].l); }ll getmax(ll p){ if(tree[p].r==0) return p; return getmax(tree[p].r); }
查找后继节点
ll getnext(ll val){ ll p=root,ans=2; while(p!=0){ if(tree[p].val==val){ if(tree[p].r!=0){ p=tree[p].r; while(tree[p].l!=0) p=tree[p].l; return 0; }break; }if(tree[p].val>val&&tree[p].val<tree[ans].val) ans=p; if(tree[p].val>val) p=tree[p].l; else p=tree[p].r; }return ans; }
删除节点
void remove(ll & p,ll val){ if(p==0) return ; if(val==tree[p].val){ if(tree[p].l==0) p=tree[p].r; else if(tree[p].r==0) p=tree[p].l; else{ ll next=tree[p].r; while(tree[next].l>0) next=tree[next].l; remove(tree[p].r,tree[next].val); tree[next].l=tree[p].l; tree[next].r=tree[p].r; p=next; }return ; }if(val<tree[p].val) remove(tree[p].l,val); else remove(tree[p].r,val); }
标签:return,val,ll,tree,二叉,查找,next From: https://www.cnblogs.com/lutaoquan/p/17981653