平衡二叉搜索树(AVL树)

来源:互联网 发布:树莓派3 ubuntu 编辑:程序博客网 时间:2024/05/16 07:03
#pragma once#ifndef _AVLTREE_H_#define _AVLTREE_H_#include <stack>#include <assert.h>struct Student{long key;char name[12];char sex;char address[12];};struct AVLNode                                                                      //AVL树结点的类定义;{Student data;AVLNode *left, *right;int bf;                                                                                    //平衡因子;AVLNode() : left(NULL), right(NULL), bf(0) { }AVLNode(Student d, AVLNode *l=NULL, AVLNode *r=NULL) : data(d), left(l), right(r), bf(0) { }};class AVLTree{public:AVLTree() : root(NULL) { }AVLTree(const long Ref) : RefValue(Ref), root(NULL) { }AVLNode *Search(const long x) {return Search(x, root);}bool Insert(Student& e1) {return Insert(root, e1);}                  //AVL树的插入算法;bool Remove(const long x, Student& e1) {return Remove(root, x, e1);}     //AVL树的删除算法;//int Height() const;private:AVLNode *Search(const long x, AVLNode *ptr){if(ptr==NULL) return NULL;else if(x<ptr->data.key) return Search(x, ptr->left);else if(x>ptr->data.key) return Search(x, ptr->right);else return ptr;}bool Insert(AVLNode *&ptr, Student& e1){AVLNode *pr=NULL, *p=ptr, *q;int d;std::stack<AVLNode *> st;while(p!=NULL)                                                               //寻找插入位置;{if(e1.key==p->data.key) return false;                                   //找到等于e1的结点,不插入;pr=p; st.push(pr);                                                       //否则用栈记忆查找路径;if(e1.key<p->data.key) p=p->left;else p=p->right;}p=new AVLNode(e1); assert(p!=NULL);if(pr==NULL) {ptr=p; return true;}                              //空树,新节点成为根结点;if(e1.key<pr->data.key) pr->left=p;                           //新结点插入;else pr->right=p;while(st.empty()==false)                                               //重新平衡化;{pr=st.top(); st.pop();if(p==pr->left) pr->bf--;else pr->bf++;if(pr->bf==0) break;if(pr->bf==1||pr->bf==-1) p=pr;else{d=(pr->bf<0) ? -1 : 1;if(p->bf==d){if(d==-1) RotateR(pr);else RotateL(pr);}else{if(d==-1) RotateLR(pr);else RotateRL(pr);}break;}}if(st.empty()==true) ptr=pr;else{q=st.top();if(q->data.key>pr->data.key) q->left=pr;else q->right=pr;}return true;}bool Remove(AVLNode *&ptr, long x, Student& e1){AVLNode *pr=NULL, *p=ptr, *q, *ppr;int d, dd=0;std::stack<AVLNode *> st;while(p!=NULL){if(x==p->data.key) break;pr=p; st.push(pr);if(x<p->data.key) p=p->left;else p=p->right;}if(p==NULL) return false;if(p->left!=NULL&&p->right!=NULL){pr=p; st.push(pr);q=p->left;while(q->right!=NULL) {pr=q; st.push(pr); q=q->right;}p->data=q->data;p=q;}if(p->left!=NULL) q=p->left;else q=p->right;if(ptr==NULL) ptr=q;else{if(pr->left==p) pr->left=q;else pr->right=q;while(st.empty()==false){pr=st.top(); st.pop();if(pr->right==q) pr->bf--;else pr->bf++;if(st.empty()==false){ppr=st.top();dd=(ppr->left==pr) ? -1 : 1;}else dd=0;if(pr->bf==1||pr->bf==-1) break;if(pr->bf!=0){if(pr->bf<0) {d=-1; q=pr->left;}else {d=1; q=pr->right;}if(q->bf==0){if(d==-1) {RotateR(pr); pr->bf=1; pr->left->bf=-1;}else {RotateL(pr); pr->bf=-1; pr->right->bf=1;}break;}if(q->bf==d){if(d==-1) RotateR(pr);else RotateL(pr);}else{if(d==-1) RotateLR(pr);else RotateRL(pr);}if(dd==-1) ppr->left=pr;else if(dd==1) ppr->right=pr;}q=pr;}if(st.empty()==true) ptr=pr;}delete p; return true;}void RotateL(AVLNode *&ptr)                            //左单旋转;{AVLNode *subL=ptr;ptr=subL->right; subL->right=ptr->left; ptr->left=subL;ptr->bf=subL->bf=0;}void RotateR(AVLNode *&ptr)                            //右单旋转;{AVLNode *subR=ptr;ptr=subR->left; subR->left=ptr->right; ptr->right=subR;ptr->bf=subR->bf=0;}void RotateLR(AVLNode *&ptr)                          //先左后右双旋转;{AVLNode *subR=ptr, *subL=subR->left;ptr=subL->right;subL->right=ptr->left;ptr->left=subL;if(ptr->bf<=0) subL->bf=0;else subL->bf=-1;subR->left=ptr->right;ptr->right=subR;if(ptr->bf==-1) subR->bf=1;else subR->bf=0;ptr->bf=0;}void RotateRL(AVLNode *&ptr)                          //先右后左双旋转;{AVLNode *subL=ptr, *subR=subL->right;ptr=subR->left;subR->left=ptr->right;ptr->right=subR;if(ptr->bf>=0) subR->bf=0;else subR->bf=1;subL->right=ptr->left;ptr->left=subL;if(ptr->bf==1) subL->bf=-1;else subL->bf=0;ptr->bf=0;}private:AVLNode *root;long RefValue;};#endif