标签:lib target 先序遍历 ++ scanf open alt 左右 contest
花了半天时间学习AVL树,AVL树只要有LL,RR,LR,RL四种旋转操作,动态增加与减少都需要四种操作结合。AVL树比普通二叉树的结构体多了一个高度,用于保证左右子节点高度差小于2。在计算高度的时候,最好自己写一个函数,因为要判断是否为NULL,NULL则表示为0。如果用指针去取高度,为NULL的时候会报错。并且在计算高度差的时候,要注意是左节点减去右节点还是右节点减去左节点。
主要灵感来源于:http://blog.csdn.net/whucyl/article/details/17289841
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<algorithm> #include<cmath> using namespace std; struct Node { int val; int height; Node* left; Node* right; Node() { height = 1; left = NULL; right = NULL; } //更新高度 void UpdateHeight() { int leftheight = left ? left->height : 0; int rightheight = right ? right->height : 0; height = max(leftheight,rightheight)+1; } //左右子孩子高度差 int DisHeight() { int leftheight = left ? left->height : 0; int rightheight = right ? right->height : 0; return leftheight-rightheight; } }; Node* LL(Node* anode) { Node* bnode = anode->left; Node* cnode = bnode->right; bnode->right = anode; anode->left = cnode; //更新高度时,anode一定要先更新 anode->UpdateHeight(); bnode->UpdateHeight(); return bnode; } Node* RR(Node* anode) { Node* bnode = anode->right; Node* cnode = bnode->left; bnode->left = anode; anode->right = cnode; anode->UpdateHeight(); bnode->UpdateHeight(); return bnode; } Node* LR(Node* anode) { anode->left = RR(anode->left); return LL(anode); } Node* RL(Node* anode) { anode->right = LL(anode->right); return RR(anode); } Node* Insert(Node* node,int val) { if(node == NULL) { node = new Node(); node->val = val; } else if(val > node->val) { node->right = Insert(node->right,val); int disH = node->DisHeight(); if(disH == -2) { if(val > node->right->val) node = RR(node); else node = RL(node); } } else if(val < node->val) { node->left = Insert(node->left,val); int disH = node->DisHeight(); if(disH == 2) { if(val < node->left->val) node = LL(node); else node = LR(node); } } node->UpdateHeight(); return node; } Node* Delete(Node* node,int val) { if(node == NULL){return NULL;} else if(node->val < val) { node->right = Delete(node->right,val); } else if(node->val > val) { node->left = Delete(node->left,val); } else { if(node->left) { Node* nd; for(nd=node->left;nd->right != NULL;nd = nd->right); node->val = nd->val; node->left = Delete(node->left,nd->val); } else if(node->right) { Node* nd; for(nd=node->right;nd->left != NULL;nd = nd->left); node->val = nd->val; node->right = Delete(node->right,nd->val); } else { delete node; return NULL; } } if(node->DisHeight()==2) { if(node->left->DisHeight()==1) node = LL(node); else node = LR(node); } else if(node->DisHeight()==-2) { if(node->right->DisHeight()==-1) node = RR(node); else node = RL(node); } node->UpdateHeight(); return node; } void pre_travel(Node* node) { if(node==NULL) return; printf("%d ",node->val); pre_travel(node->left); pre_travel(node->right); } void in_travel(Node* node) { if(node==NULL) return; in_travel(node->left); printf("%d ",node->val); in_travel(node->right); } int main() { //test code Node *root = NULL; root = Insert(root,5); root = Insert(root,6); root = Insert(root,3); root = Insert(root,2); root = Insert(root,4); root = Insert(root,1); root = Insert(root,9); root = Insert(root,8); root = Insert(root,7); printf("先序遍历:\n"); pre_travel(root); printf("\n"); printf("中序遍历:\n"); in_travel(root); printf("\n"); root = Delete(root,6); root = Delete(root,1); printf("\n先序遍历:\n"); pre_travel(root); printf("\n"); printf("中序遍历:\n"); in_travel(root); printf("\n"); return 0; }
PAT1066,简单AVL的插入操作。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<vector> #include<algorithm> using namespace std; struct Node { int val; int H; Node* left; Node* right; Node() { H = 1; left = NULL; right = NULL; } int LH(){return left?left->H:0;} int RH(){return right?right->H:0;} void UpdateH(){H = max(LH(),RH())+1;} int DisH(){return LH() - RH();} }; Node* LL(Node* anode) { Node *bnode = anode->left; Node *cnode = bnode->right; bnode->right = anode; anode->left = cnode; anode->UpdateH(); bnode->UpdateH(); return bnode; } Node* RR(Node* anode) { Node *bnode = anode->right; Node *cnode = bnode->left; bnode->left = anode; anode->right = cnode; anode->UpdateH(); bnode->UpdateH(); return bnode; } Node* LR(Node* anode) { anode->left = RR(anode->left); return LL(anode); } Node* RL(Node* anode) { anode->right = LL(anode->right); return RR(anode); } Node* Insert(Node* node,int val) { if(node==NULL) { node = new Node(); node->val = val; } else if(val > node->val) { node->right = Insert(node->right,val); if(node->DisH()==-2) { if(val > node->right->val) node = RR(node); else node = RL(node); } } else if(val < node->val) { node->left = Insert(node->left,val); if(node->DisH()==2) { if(val < node->left->val) node = LL(node); else node = LR(node); } } node->UpdateH(); return node; } int main() { int n; scanf("%d",&n); Node* root = NULL; for(int i=0;i<n;++i) { int val; scanf("%d",&val); root = Insert(root,val); } printf("%d\n",root->val); return 0; }
标签:lib target 先序遍历 ++ scanf open alt 左右 contest
原文地址:http://www.cnblogs.com/jlyg/p/7521434.html