二叉查詢樹&&平衡樹基礎
阿新 • • 發佈:2019-02-11
操作:二叉查詢樹(插入,查詢,刪除,dfs序,求最值,第k大/小)
//二叉查詢樹 //特點:每個點左子樹上的點都小於該點,右子樹上的點都大於該點 //沒有取值相同的點 任意點的左右子樹均為二叉查詢樹 //中序遍歷嚴格單調遞增 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; struct uio{ int num,cnt,dfs;//num取值 cnt該取值個數 dfs為dfs序 int l,r;//左右子節點的編號 }bst[1001]; int n,root,ccnt=1,midcnt,ans[1000];//root為最終父節點(根節點) ccnt為輸入資料編號 midcnt為中序遍歷編號 void get(int x)//插入 { ccnt++; int pre=0,now=1; while(now!=0) { if(x==bst[now].num) { bst[now].cnt++; return; } if(x<bst[now].num) { pre=now; now=bst[now].l; } if(x>bst[now].num) { pre=now; now=bst[now].r; } } bst[ccnt].num=x; bst[ccnt].cnt=1; if(x<bst[pre].num) bst[pre].l=ccnt; else bst[pre].r=ccnt; } int search(int x)//查詢 { int now=1; while(now!=0) { if(x==bst[now].num) return now; if(x<bst[now].num) now=bst[now].l; if(x>bst[now].num) now=bst[now].r; } return 0; } int getpre(int x) { int pre=0,now=1; while(now!=0) { if(x==bst[now].num) return pre; if(x<bst[now].num) { pre=now; now=bst[now].l; } if(x>bst[now].num) { pre=now; now=bst[now].r; } } return 0; } int getnxt(int x) { if(bst[x].l==0) return x; return getnxt(bst[x].l); } void del(int x)//刪除 { int pre=getpre(x); int now=search(x); if(bst[now].num>1) { bst[now].num--; return; } if(bst[now].l==0&&bst[now].r==0) { if(bst[pre].l==now) bst[pre].l=0; else bst[pre].r=0; } if(bst[now].l!=0&&bst[now].r==0) { bst[pre].l=bst[now].l; if(bst[pre].r==now) bst[pre].r=0; } if(bst[now].l==0&&bst[now].r!=0) { bst[pre].r=bst[now].r; if(bst[pre].l==now) bst[pre].l=0; } if(bst[now].l!=0&&bst[now].r!=0) { int nxt=getnxt(now); swap(bst[now],bst[nxt]); del(bst[nxt].num); } } int getmin(int x)//找最小值 返回下標 { int ans=0,now=1; while(now!=0) { if(bst[now].num<x) { ans=now; now=bst[now].r; } else now=bst[now].l; } return ans; } int getmax(int x)//找最大值 返回下標 { int ans=0,now=1; if(bst[now].num>x) { ans=now; now=bst[now].l; } else now=bst[now].r; } int dfsnummin(int x,int y)//dfs序(升序) x起始點編號 y記序 { if(bst[x].l!=0) dfsnummin(bst[x].l,y+1); if(bst[x].r!=0) dfsnummin(bst[x].r,y+1); bst[x].dfs=y; } int getnokmin(int x,int k)//找第k小 { dfsnummin(1,1); int now=1; while(now!=0) { int lsize=0; int lson=bst[now].l; int rson=bst[now].r; if(lson!=0) lsize=bst[now].dfs; if(x<=lsize)//x在左子樹 now=lson; else if(lsize+1<=k&&k<=lsize+bst[now].num)//x為當前節點 return now; else//x在右子樹 { x-=lsize+bst[now].num; now=rson; } } return 0; } int dfsnummax(int x,int y)//dfs序(降序) x起始點編號 y記序 { if(bst[x].l!=0) dfsnummax(bst[x].l,y-1); if(bst[x].r!=0) dfsnummax(bst[x].r,y-1); bst[x].dfs=y; } int getnokmax(int x,int k)//找第k大 { dfsnummax(1,n); int now=1; while(now!=0) { int rsize=0; int lson=bst[now].l; int rson=bst[now].r; if(rson!=0) rsize=bst[now].dfs; if(x<=rsize)//x在右子樹 now=rson; else if(rsize+1<=k&&k<=rsize+bst[now].num)//x為當前節點 return now; else//x在左子樹 { x-=rsize+bst[now].num; now=rson; } } return 0; } void do_something() { return; } int main() { cin>>n>>root; bst[1].num=root; bst[1].cnt=1; for(int i=1;i<=n;i++) { int v=0; cin>>v; get(v); } do_something(); return 0; }