写了好久,感觉插入和删除麻烦些,插入也就4种情况,但只要写两个函数,左左和右右的,左右的情况是以根节点的左子树为头进行一次右右旋转,使它变成左左的情况,再左左旋转下就行了,右左的也一样;
另外就是删除,先是判断要删除的节点右儿子是否为空,是空,直接删,否则找到它右儿子的最左边的儿子来替代它,然后就是高度的更新,重新的旋转。。。
哎,真实花了我好长时间,不过终于写完了。大致感觉没啥问题了吧,有的话以后再改吧。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <stdlib.h> #include <cmath> using namespace std; typedef struct AvlNode // AVL树的节点 { int data; struct AvlNode *left; // 左孩子 struct AvlNode *right; // 右孩子 int Height; }*Position,*AvlTree; AvlTree MakeEmpty(AvlTree T); Position Find(int x,AvlTree T); Position Find_right(AvlTree T); Position FindMax(AvlTree T); int Search(AvlTree T); AvlTree Insert(int x,AvlTree T); AvlTree Delete(int x,AvlTree T); AvlTree left_left(AvlTree k1); AvlTree right_right(AvlTree k1); AvlTree left_right(AvlTree k1); AvlTree right_left(AvlTree k1); AvlTree Printf_tree(AvlTree T); AvlTree balance(AvlTree T); int main() { AvlTree T =NULL; getchar(); T=Insert(2,T); T= Insert(7,T); //Printf_tree(T); T= Insert(5,T); //Printf_tree(T); T=Insert(11,T); T=Insert(9,T); T=Insert(10,T); T=Insert(100,T); T=Insert(14,T); T=Insert(20,T); Printf_tree(T); T = Delete(5,T); printf(" "); Printf_tree(T); printf(" "); T = Delete(2,T); Printf_tree(T); getchar(); return 0; } AvlTree MakeEmpty(AvlTree T) { if(T!=NULL) { MakeEmpty(T->left); MakeEmpty(T->right); free(T); } return NULL; } int height(AvlTree T) { if(T==NULL)return -1; else return T->Height; } //向树中插入数据 AvlTree Insert(int x,AvlTree T) { if(T==NULL) { T = (AvlTree)malloc(sizeof(struct AvlNode)); T->data = x; T->Height = 0; T->left = NULL; T->right = NULL; } //如果插入元素小于当前元素 else if(x<T->data) { T->left = Insert(x,T->left); if(height(T->left)-height(T->right)==2) { if(x<T->left->data) T = left_left(T); else T = left_right(T); } } else if(x>T->data) { T->right = Insert(x,T->right); if(height(T->right)-height(T->left)==2) { if(x<T->right->data) T = right_left(T); else T = right_right(T); } } T->Height = max(height(T->left),height(T->right))+1; return T; } //左左旋转 AvlTree left_left(AvlTree k1) { //if(height(k1->left)-height(k1->right)<2)return k1; AvlTree k2 = k1->left; k1->left = k2->right; k2->right = k1; k1->Height = max(height(k1->left),height(k1->right))+1; k2->Height = max(height(k2->left),height(k2->right))+1; return k2; } //右右旋转 AvlTree right_right(AvlTree k1) { //if(height(k1->right)-height(k1->left)<2)return k1; AvlTree k2 = k1->right; k1->right = k2->left; k2->left = k1; k1->Height = max(height(k1->left),height(k1->right))+1; k2->Height = max(height(k2->left),height(k2->right))+1; return k2; } //左右旋转 AvlTree left_right(AvlTree k1) { k1->left = right_right(k1->left); return left_left(k1); } //右左旋转 AvlTree right_left(AvlTree k1) { k1->right = left_left(k1->right); return right_right(k1); } AvlTree Printf_tree(AvlTree T) { if(T==NULL)return NULL; else { printf("父亲节点是:%d ",T->data); printf("左儿子是: "); if(T->left==NULL)printf("NULL"); else printf("%d",T->left->data); printf("右儿子是:"); if(T->right==NULL)printf("NULL"); else printf("%d",T->right->data); printf(" 高度是:%d ",height(T)); } Printf_tree(T->left); Printf_tree(T->right); } AvlTree Delete(int x,AvlTree T) { if(T==NULL)return NULL; else { if(T->data==x) { if(T->right==NULL) { AvlTree tem = T; T = T->left; free(tem); } else { AvlTree tem = T->right; while(tem->left!=NULL) { tem = tem->left; } T->data = tem->data; //free(tem); //tem=NULL; T->right = Delete(T->data,T->right); T->Height = max(height(T->left),height(T->right))+1; } return T; } else if(x>T->data) { T->right = Delete(x,T->right); } else if(x<T->data) { T->left = Delete(x,T->left); } //删除后判断是否平衡,不平衡则需旋转 T->Height = max(height(T->left),height(T->right))+1; if(T->left!=NULL) { T->left = balance(T->left); } if(T->right!=NULL) { T->right = balance(T->right); } if(T!=NULL) { T = balance(T); } return T; } } AvlTree balance(AvlTree T) { if(height(T->left)-height(T->right)==2) { if(height(T->left->left)>height(T->left->right)) { T = left_left(T); } else { T = left_right(T); } } else if(height(T->right)-height(T->left)==2) { if(height(T->right)-height(T->left)) { T = right_right(T); } else { T = right_left(T); } } else { return T; } }
http://poj.org/problem?id=3481
POJ 3481
大意3中操作,1是插入数据,2是输出优先级最大的编号,3是输出优先级最小的编号,一遍过
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <stdlib.h> #include <cmath> using namespace std; typedef struct _DATA { int answer; int pori; }DATA; typedef struct AvlNode // AVL树的节点 { DATA data; struct AvlNode *left; // 左孩子 struct AvlNode *right; // 右孩子 int Height; }*Position,*AvlTree; AvlTree MakeEmpty(AvlTree T); Position Find(int x,AvlTree T); Position Find_right(AvlTree T); Position FindMax(AvlTree T); int Search(AvlTree T); AvlTree Insert(DATA x,AvlTree T); AvlTree Delete(DATA x,AvlTree T); AvlTree left_left(AvlTree k1); AvlTree right_right(AvlTree k1); AvlTree left_right(AvlTree k1); AvlTree right_left(AvlTree k1); AvlTree Printf_tree(AvlTree T); AvlTree balance(AvlTree T); DATA Find_max(AvlTree T); DATA Find_min(AvlTree T); int main() { int n; AvlTree T = NULL; while(scanf("%d",&n)!=EOF&&n) { if(n==1) { DATA a; scanf("%d%d",&a.answer,&a.pori); T = Insert(a,T); } if(n==2) { if(T==NULL)printf("0 "); else { DATA tem = Find_max(T); T = Delete(tem,T); printf("%d ",tem.answer); } } if(n==3) { if(T==NULL)printf("0 "); else { DATA tem = Find_min(T); T = Delete(tem,T); printf("%d ",tem.answer); } } } return 0; } AvlTree MakeEmpty(AvlTree T) { if(T!=NULL) { MakeEmpty(T->left); MakeEmpty(T->right); free(T); } return NULL; } int height(AvlTree T) { if(T==NULL)return -1; else return T->Height; } //向树中插入数据 AvlTree Insert(DATA x,AvlTree T) { if(T==NULL) { T = (AvlTree)malloc(sizeof(struct AvlNode)); T->data = x; T->Height = 0; T->left = NULL; T->right = NULL; } //如果插入元素小于当前元素 else if(x.pori<T->data.pori) { T->left = Insert(x,T->left); if(height(T->left)-height(T->right)==2) { if(x.pori<T->left->data.pori) T = left_left(T); else T = left_right(T); } } else if(x.pori>T->data.pori) { T->right = Insert(x,T->right); if(height(T->right)-height(T->left)==2) { if(x.pori<T->right->data.pori) T = right_left(T); else T = right_right(T); } } T->Height = max(height(T->left),height(T->right))+1; return T; } //左左旋转 AvlTree left_left(AvlTree k1) { //if(height(k1->left)-height(k1->right)<2)return k1; AvlTree k2 = k1->left; k1->left = k2->right; k2->right = k1; k1->Height = max(height(k1->left),height(k1->right))+1; k2->Height = max(height(k2->left),height(k2->right))+1; return k2; } //右右旋转 AvlTree right_right(AvlTree k1) { //if(height(k1->right)-height(k1->left)<2)return k1; AvlTree k2 = k1->right; k1->right = k2->left; k2->left = k1; k1->Height = max(height(k1->left),height(k1->right))+1; k2->Height = max(height(k2->left),height(k2->right))+1; return k2; } //左右旋转 AvlTree left_right(AvlTree k1) { k1->left = right_right(k1->left); return left_left(k1); } //右左旋转 AvlTree right_left(AvlTree k1) { k1->right = left_left(k1->right); return right_right(k1); } /*AvlTree Printf_tree(AvlTree T) { if(T==NULL)return NULL; else { printf("父亲节点是:%d ",T->data); printf("左儿子是: "); if(T->left==NULL)printf("NULL"); else printf("%d",T->left->data); printf("右儿子是:"); if(T->right==NULL)printf("NULL"); else printf("%d",T->right->data); printf(" 高度是:%d ",height(T)); } Printf_tree(T->left); Printf_tree(T->right); }*/ AvlTree Delete(DATA x,AvlTree T) { if(T==NULL)return NULL; else { if(T->data.pori==x.pori) { if(T->right==NULL) { AvlTree tem = T; T = T->left; free(tem); } else { AvlTree tem = T->right; while(tem->left!=NULL) { tem = tem->left; } T->data = tem->data; //free(tem); //tem=NULL; T->right = Delete(T->data,T->right); T->Height = max(height(T->left),height(T->right))+1; } return T; } else if(x.pori>T->data.pori) { T->right = Delete(x,T->right); } else if(x.pori<T->data.pori) { T->left = Delete(x,T->left); } //删除后判断是否平衡,不平衡则需旋转 T->Height = max(height(T->left),height(T->right))+1; if(T->left!=NULL) { T->left = balance(T->left); } if(T->right!=NULL) { T->right = balance(T->right); } if(T!=NULL) { T = balance(T); } return T; } } AvlTree balance(AvlTree T) { if(height(T->left)-height(T->right)==2) { if(height(T->left->left)>height(T->left->right)) { T = left_left(T); } else { T = left_right(T); } } else if(height(T->right)-height(T->left)==2) { if(height(T->right)-height(T->left)) { T = right_right(T); } else { T = right_left(T); } } else { return T; } } DATA Find_max(AvlTree T) { AvlTree tem = T; while(tem->right!=NULL) { tem = tem->right; } return tem->data; } DATA Find_min(AvlTree T) { AvlTree tem = T; while(tem->left!=NULL) { tem = tem->left; } return tem->data; }