1 /****************************************************************** 2 题目: Double Queue(poj 3481) 3 链接: http://poj.org/problem?id=3481 4 算法: avl树(入门) 5 *******************************************************************/ 6 #include<cstdio> 7 #include<cstring> 8 #include<cstdlib> 9 #include<iostream> 10 #include<algorithm> 11 using namespace std; 12 13 typedef struct Node ///树的节点 14 { 15 int val,data; 16 int h; ///以当前结点为根结点的数的高度 17 int bf; ///平衡因子(左子树高度与右子树高度之差) 18 Node *left,*right; 19 }Node; 20 21 class AvlTree ///alv树,树中太多函数,用类来实现容易一些 22 { 23 private: 24 Node *root; ///树的根节点 25 public: 26 void Init() ///初始化树 27 { 28 root=NULL; 29 } 30 int Height(Node *T) ///取一个节点的高度 31 { 32 if (T==NULL) return 0; 33 return T->h; 34 } 35 int Bf(Node *T) ///计算一个节点的平衡因子 36 { 37 if (T->left==T->right) return 0; 38 if (T->left==NULL) return -(T->right->h); ///这里一定取负数(左子树高度与右子树高度之差) 39 if (T->right==NULL) return T->left->h; 40 return (T->left->h)-(T->right->h); 41 } 42 ///四种旋转,不知为什么,自己多画一下就知道了。 43 Node *LL_rotate(Node *T) ///单向右旋平衡处理LL:由于在*T的左子树根结点的左子树上插入结点 44 { 45 Node *B=T->left; 46 T->left=B->right; 47 B->right=T; 48 T->h=max(Height(T->left),Height(T->right))+1; 49 B->h=max(Height(B->left),Height(T->right))+1; 50 T->bf=Bf(T); 51 B->bf=Bf(B); 52 return B; 53 } 54 Node *RR_rotate(Node *T) ///单向左旋平衡处理RR:由于在*T的右子树根结点的右子树上插入结点 55 { 56 Node *B=T->right; 57 T->right=B->left; 58 B->left=T; 59 T->h=max(Height(T->left),Height(T->right))+1; 60 B->h=max(Height(B->left),Height(T->right))+1; 61 T->bf=Bf(T); 62 B->bf=Bf(B); 63 return B; 64 } 65 Node *LR_rotate(Node *T) ///双向旋转平衡处理LR:由于在*T的左子树根结点的右子树上插入结点 66 { 67 T->left=RR_rotate(T->left); 68 T=LL_rotate(T); 69 return T; 70 } 71 Node *RL_rotate(Node *T) ///双向旋转平衡处理RL:由于在*T的右子树根结点的左子树上插入结点 72 { 73 T->right=LL_rotate(T->right); 74 T=RR_rotate(T); 75 return T; 76 } 77 void Insert(int v,int e) ///root是private,所以不能从主函数传入 78 { 79 Insert(root,v,e); 80 } 81 void Insert(Node *&T,int v,int e) ///插入新节点 82 { 83 if (T==NULL) 84 { 85 T=(Node *)malloc(sizeof(Node)); 86 T->h=1; 87 T->bf=0; 88 T->val=v; 89 T->data=e; 90 T->left=T->right=NULL; 91 return ; 92 } 93 if (e<T->data) Insert(T->left,v,e); 94 else Insert(T->right,v,e); 95 T->h=max(Height(T->left),Height(T->right))+1; ///计算节点高度 96 T->bf=Bf(T); ///计算平衡因子 97 if (T->bf>1||T->bf<-1) ///调整平衡,四种调整反法 98 { 99 if (T->bf>1&&T->left->bf>0) T=LL_rotate(T); ///如果T->bf > 1 则肯定有左儿子 100 if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T); ///如果T->bf < -1 则肯定有右儿子 101 if (T->bf>1&&T->left->bf<0) T=LR_rotate(T); 102 if (T->bf<-1&&T->right>0) T=RL_rotate(T); 103 } 104 } 105 void Find(int flag) ///flag=1为找最大值,否则找最小值 106 { 107 if (root==NULL) 108 { 109 printf("0\n"); 110 return ; 111 } 112 Node *temp=root; 113 if (flag) ///最大值一定最右边 114 { 115 while (temp->right) 116 temp=temp->right; 117 } 118 else 119 { 120 while (temp->left) 121 temp=temp->left; 122 } 123 printf("%d\n",temp->val); 124 Delete(root,temp->data); ///删除相应节点 125 } 126 void Delete(Node *&T,int e) 127 { 128 if (T==NULL) return ; 129 if (e<T->data) Delete(T->left,e); 130 else if (e>T->data) Delete(T->right,e); 131 else ///找到删除的节点 132 { 133 if (T->left&&T->right) ///删除的节点左右都还有节点 134 { 135 Node *temp=T->left; ///把左子树的最大值当做当前节点 136 while (temp->right) temp=temp->right; ///找最大值 137 T->val=temp->val; 138 T->data=temp->data; 139 Delete(T->left,temp->data); ///左子树最大值已近改为当前根节点,应该删除原来位置 140 } 141 else 142 { 143 Node *temp=T; 144 if (T->left) T=T->left; ///删除节点只存在左子树 145 else if (T->right) T=T->right; ///删除节点只有右子树 146 else ///删除节点没有孩子 147 { 148 free(T); 149 T=NULL; 150 } 151 if (T) free(temp); 152 return ; 153 } 154 } 155 T->h=max(Height(T->left),Height(T->right))+1; 156 T->bf=Bf(T); 157 if (T->bf>1||T->bf<-1) ///删除后一定要调整 158 { 159 if (T->bf>1&&T->left->bf>0) T=LL_rotate(T); 160 if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T); 161 if (T->bf>1&&T->left->bf<0) T=LR_rotate(T); 162 if (T->bf<-1&&T->right>0) T=RL_rotate(T); 163 } 164 } 165 void Free() ///由于内存是malloc出来的,最后一定要释放 166 { 167 FreeNode(root); 168 } 169 void FreeNode(Node *T) 170 { 171 if (T==NULL) return ; 172 if (T->right) FreeNode(T->right); 173 if (T->left) FreeNode(T->left); 174 free(T); 175 } 176 }; 177 AvlTree T; 178 179 int main() 180 { 181 T.Init(); 182 int op; 183 while (~scanf("%d",&op)&&op) 184 { 185 if (op==1) 186 { 187 int v,e; 188 scanf("%d%d",&v,&e); 189 T.Insert(v,e); 190 } 191 if (op==2) 192 { 193 T.Find(1); 194 } 195 if (op==3) 196 { 197 T.Find(0); 198 } 199 } 200 T.Free(); 201 return 0; 202 }