AVL平衡樹(二叉搜尋樹 c++實現)
阿新 • • 發佈:2019-01-28
程式碼:
指標實現
/*仿一個部落格的AVL*/ #include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #include<cmath> #include<map> #include<stack> #include<queue> #include<ctime> #include<cstring> #include<string> #define LL __int64 #define INF 0x3f3f3f3f3f using namespace std; struct node { int val; int height; node* l; node* r; }; node root; int max(int a, int b) { return a>b; } int height(node *p) { if(p) return p->height; return 0; } node* maximum(node* p) { if(p) { while(p->r) p=p->r; return p; } return NULL; } node* minimum(node* p) { if(p) { while(p->l) p=p->l; return p; } return NULL; } node* LeftRotation(node* p) { node *q = p->r; p->r = q->l; q->l = p; p->height = max(height(p->l), height(p->r)) + 1; q->height = max(height(q->l), height(q->r)) + 1; return q; } node* RightRotation(node* p) { node *q = p->l; p->l = q->r; q->r = p; p->height = max(height(p->l), height(p->r)) + 1; q->height = max(height(q->l), height(q->r)) + 1; return q; } node* RLeftRotation(node* p) { p->r = RightRotation(p->r); return LeftRotation(p); } node* LRightRotation(node* p) { p->l = LeftRotation(p->l); return RightRotation(p); } node* InsertNode(node* &p, int val) { if(!p) { p = new node; p->height=0; p->l=NULL; p->r=NULL; p->val=val; } else if(val > p->val) { p->r = InsertNode(p->r, val); if(height(p->r) - height(p->l)==2) //插入失衡 { if(val > p->r->val) p = LeftRotation(p); else p = RLeftRotation(p); } } else if(val < p->val) { p->l = InsertNode(p->l, val); if(height(p->l) - height(p->r)==2) //插入失衡 { if(val < p->l->val) p = RightRotation(p); else p = LRightRotation(p); } } p->height = max(height(p->l), height(p->r)) + 1; return p; } node* del(node* &p, int val) { if(p) { if(val == p->val) { if(p->l && p->r)//左右都不為空 { if(height(p->l) > height(p->r)) { node* q = maximum(p->l); p->val = q->val; p->l = del(p->l, q->val); } else { node* q = minimum(p->r); p->val = q->val; p->r = del(p->r, q->val); } } else { node* q = p; if(p->l) p=p->l; else if(p->r) p=p->r; return NULL; } } else if(val > p->val) { p->r = del(p->r, val); if(height(p->l) - height(p->r) == 2) { if(height(p->l->r)>height(p->l->l)) { p = LRightRotation(p); } else p = RightRotation(p); } } else if(val < p->val) { p->l = del(p->l, val); if(height(p->r) - height(p->l) ==2) { if(height(p->r->l)>height(p->r->r)) { p=RLeftRotation(p); } else p = LeftRotation(p); } } return p; } return NULL; } int query(int x) { node *p=root.l; int k=0; stack<node*>S; if(!p) return false; while(p || !S.empty()) { while(p) { S.push(p); p=p->l; } p=S.top(); S.pop(); k++; if(k==x) { return p->val; break; } p=p->r; } return false; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,x; char c[4]; scanf("%d", &n); root.l=root.r=NULL; while(n--) { scanf("%s", c); if(c[0]=='Y') printf("Single dog!\n"); else { scanf("%d", &x); if(c[0]=='J') InsertNode(root.l, x); else if(c[0]=='W') printf("%d\n", query(x)); else if(c[0]=='X') del(root.l, x); } } return 0; }
陣列實現:
/*************** Problem from :資料結構 Problem describe :平衡樹的應用 ****************/ #include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #include<cmath> #include<map> #include<stack> #include<queue> #include<ctime> #include<cstring> #include<string> #define LL __int64 #define INF 0x3f3f3f3f3f using namespace std; struct Tree{ int key, l, r, size; }node[111111]; int root=0, top=0; void left_rotation(int &x) { int y = node[x].r; node[x].r = node[y].l; node[y].l = x; node[y].size = node[x].size; node[x].size = node[node[x].l].size + node[node[x].r].size+1; x = y; } void right_rotation(int &x) { int y = node[x].l; node[x].l = node[y].r; node[y].r = x; node[y].size = node[x].size; node[x].size = node[node[x].l].size + node[node[x].r].size+1; x = y; } void maintain(int &root, bool flag) { if(flag == false)//false => 左 { // root 的左兒子的左兒子的size>root的右兒子的size if(node[node[node[root].l].l].size > node[node[root].r].size) { right_rotation(root); } // root 的左兒子的右兒子的size>root的右兒子的size else if(node[node[node[root].l].r].size > node[node[root].r].size) { left_rotation(node[root].l); right_rotation(root); } else return ; } else { // root 的右兒子的右兒子的size>root的左兒子的size if(node[node[node[root].r].r].size > node[node[root].l].size) { left_rotation(root); } // root 的右兒子的左兒子的size>root的右兒子的size else if(node[node[node[root].r].l].size > node[node[root].l].size) { right_rotation(node[root].r); left_rotation(root); } else return ; } maintain(node[root].l,false); maintain(node[root].r,true); maintain(root,true); maintain(root,false); } void insert(int &root, int key) { if(root==0) { root=++top; node[root].l = node[root].r = 0; node[root].size = 1; node[root].key = key; } else { node[root].size ++; if(key < node[root].key) insert(node[root].l, key); else insert(node[root].r, key); maintain(root, key>=node[root].key); } return ; } int remove(int &root, int key) { int d_key; node[root].size--; if( key == node[root].key || (key > node[root].key&& node[root].r==0) || (key < node[root].key&& node[root].l==0)) { d_key = node[root].key; if(node[root].l && node[root].r) { node[root].key = remove(node[root].l,node[root].key+1); } else { root = node[root].l + node[root].r; } } else if(key > node[root].key) { d_key = remove(node[root].r, key); } else { d_key = remove(node[root].l, key); } return d_key; } int select(int &root,int k)//求第k小數 { int r = node[node[root].l].size + 1; if(r == k) return node[root].key; else if(r < k) return select(node[root].r,k - r); else return select(node[root].l,k); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,cnt=0,x; char c[4]; scanf("%d", &n); while(n--) { scanf("%s", c); if(c[0]=='Y') printf("Single dog!\n"); else { scanf("%d", &x); if(c[0]=='J') insert(root, x), cnt++; else if(c[0]=='W') printf("%d\n", (x>cnt)?0:select(root, x)); else if(c[0]=='X') remove(root, x), cnt--; } } return 0; }