(转)AVL树的插入_删除操作
来源:互联网 发布:中国未来 知乎 编辑:程序博客网 时间:2024/06/06 03:17
版本1:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <assert.h>typedef struct node node;struct node{ node* parent; node* left; node* right; int balance; //左右子树高度之差 int key;};extern void traverseAVL1(node* root); //中序遍历, 下面定义extern void traverseAVL2(node* root); //前序遍历, 下面定义int searchNode(int key, node* root, node** parent) //按key查找结点{ node* temp; assert(root != NULL); temp = root; *parent = root->parent; while (temp !=NULL) { if (temp->key == key) return 1; else { *parent = temp; if (temp->key > key) temp = temp->left; else temp = temp->right; } } return 0;}node* minNode(node* root) //树root的最小结点{ if (root == NULL) return NULL; while (root->left != NULL) root = root->left; return root;}node* maxNode(node* root) //树root的最大结点{ if (root == NULL) return NULL; while (root->right != NULL) root = root->right; return root;}node* preNode(node* target) //求前驱结点{ if (target == NULL) return NULL; if (target->left != NULL) return maxNode(target->left); else while ((target->parent!=NULL) && (target!=target->parent->right)) target = target->parent; return target->parent;}node* nextNode(node* target) //求后继结点{ if (target == NULL) return NULL; if (target->right != NULL) return minNode(target->right); else while ((target->parent!=NULL) && (target!=target->parent->left)) target = target->parent; return target->parent;}node* adjustAVL(node* root, node* parent, node* child){ node *cur; assert((parent != NULL)&&(child != NULL)); switch (parent->balance) { case 2: if (child->balance == -1)//LR型 { cur = child->right; cur->parent = parent->parent; child->right = cur->left; if (cur->left != NULL) cur->left->parent = child; parent->left = cur->right; if (cur->right != NULL) cur->right->parent = parent; cur->left = child; child->parent = cur; cur->right = parent; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = cur; else parent->parent->right = cur; else root = cur; parent->parent = cur; if (cur->balance == 0) { parent->balance = 0; child->balance = 0; } else if (cur->balance == -1) { parent->balance = 0; child->balance = 1; } else { parent->balance = -1; child->balance = 0; } cur->balance = 0; } else //LL型 { child->parent = parent->parent; parent->left = child->right; if (child->right != NULL) child->right->parent = parent; child->right = parent; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = child; else parent->parent->right = child; else root = child; parent->parent = child; if (child->balance == 1) //插入时 { child->balance = 0; parent->balance = 0; } else //删除时 { child->balance = -1; parent->balance = 1; } } break; case -2: if (child->balance == 1) //RL型 { cur = child->left; cur->parent = parent->parent; child->left = cur->right; if (cur->right != NULL) cur->right->parent = child; parent->right = cur->left; if (cur->left != NULL) cur->left->parent = parent; cur->left = parent; cur->right = child; child->parent = cur; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = cur; else parent->parent->right = cur; else root = cur; parent->parent = cur; if (cur->balance == 0) { parent->balance = 0; child->balance = 0; } else if (cur->balance == 1) { parent->balance = 0; child->balance = -1; } else { parent->balance = 1; child->balance = 0; } cur->balance = 0; } else //RR型 { child->parent = parent->parent; parent->right = child->left; if (child->left != NULL) child->left->parent = parent; child->left = parent; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = child; else parent->parent->right = child; else root = child; parent->parent = child; if (child->balance == -1) //插入时 { child->balance = 0; parent->balance = 0; } else //删除时 { child->balance = 1; parent->balance = -1; } } break; } return root;}node* insertNode(int key, node* root){ node *parent, *cur, *child; assert (root != NULL); if (searchNode(key, root, &parent)) //结点已存在 return root; else { cur = (node*)malloc(sizeof(node)); cur->parent = parent; cur->key = key; cur->left = NULL; cur->right = NULL; cur->balance = 0; if (key<parent->key) { parent->left = cur; child = parent->left; } else { parent->right = cur; child = parent->right; } while ((parent != NULL)) //查找需要调整的最小子树 { if (child == parent->left) if (parent->balance == -1) { parent->balance = 0; return root; } else if (parent->balance == 1) { parent->balance = 2; break; } else { parent->balance = 1; child = parent; parent = parent->parent; } else if (parent->balance == 1) { parent->balance = 0; return root; } else if (parent->balance == -1) { parent->balance = -2; break; } else { parent->balance = -1; child = parent; parent = parent->parent; } } if (parent == NULL) return root; return adjustAVL(root, parent, child); }}node* deleteNode(int key, node* root){ node *dNode, *parent, *child, *tp; int temp, tc; assert(root!=NULL); if (!searchNode(key, root, &parent)) return root; else { if (parent == NULL) dNode = root; else if ((parent->left!=NULL)&&(parent->left->key==key)) dNode = parent->left; else dNode = parent->right; child = dNode; while ((child->left!=NULL)||(child->right!=NULL)) //确定需要删除的结点 { if (child->balance == 1) child = preNode(dNode); else child = nextNode(dNode); temp = child->key; child->key = dNode->key; dNode->key = temp; dNode = child; } child = dNode; parent = dNode->parent; while ((parent != NULL)) //查找需要调整的最小子树 { if (child == parent->left) if (parent->balance == 1) { parent->balance = 0; child = parent; parent = parent->parent; } else if (parent->balance == -1) { parent->balance = -2; child = parent->right; temp = parent->right->balance;//临时变量保存 tp = parent->parent;//临时变量保存 if (tp != NULL) if (parent == tp->left) tc = 1; else tc = -1; else tc = 0; root = adjustAVL(root, parent, child); if (temp == 0) break; else { if (tc == 1) child = tp->left; else if (tc == -1) child = tp->right; parent = tp; } } else { parent->balance = -1; break; } else if (parent->balance == -1) { parent->balance = 0; child = parent; parent = parent->parent; } else if (parent->balance == 1) { parent->balance = 2; child = parent->left; temp = parent->left->balance;//临时变量保存 tp = parent->parent;//临时变量保存 if (tp != NULL) if (parent == tp->left) tc = 1; else tc = -1; else tc = 0; root = adjustAVL(root, parent, child); if (temp == 0) break; else { if (tc == 1) child = tp->left; else if (tc == -1) child = tp->right; parent = tp; } } else { parent->balance = 1; break; } } if (dNode->parent != NULL) if (dNode == dNode->parent->left) dNode->parent->left = NULL; else dNode->parent->right = NULL; free(dNode); if (root == dNode) root = NULL; //root被删除, 避免野指针 dNode = NULL; return root; }}node* createAVL(int *data, int size){ int i, j; node *root; if (size<1) return NULL; root = (node*)malloc(sizeof(node)); root->parent = NULL; root->left = NULL; root->right = NULL; root->key = data[0]; root->balance = 0; for(i=1;i<size;i++) root = insertNode(data[i], root); return root;}void destroyAVL(node* root){ if (root != NULL) { destroyAVL(root->left); destroyAVL(root->right); free(root); root=NULL; } }void traverseAVL1(node* root) //中序遍历{ if (root != NULL) { traverseAVL1(root->left); printf("%d, %d\n", root->key, root->balance); traverseAVL1(root->right); }}void traverseAVL2(node* root) //先序遍历{ if (root != NULL) { printf("%d, %d\n", root->key, root->balance); traverseAVL2(root->left); traverseAVL2(root->right); }}int main(int argc, char *argv[]){ int data[] = {1, 5, 7, 4, 3, 2, 11, 9, 10}; node* root; root = createAVL(data, sizeof(data)/sizeof(data[0])); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); root = deleteNode(5, root); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); root = deleteNode(3, root); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); root = deleteNode(1, root); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); root = deleteNode(7, root); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); root = deleteNode(4, root); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); root = deleteNode(2, root); printf("++++++++++++++++++++++++++++\n"); traverseAVL1(root); printf("\n"); traverseAVL2(root); destroyAVL(root);}
版本2:
#include <stdio .h>#include <stdbool .h>#include <stdlib .h> char chos;int input;bool unbalanced = false;struct node{ int data; int bf; node *lchild; node *rchild;};typedef struct node *BST;BST R = NULL; void Chose(){ printf("i) Insert a point\n" "d) Delete a point\n" "e) exit\n" "Input your choose:"); scanf(" %c", &chos);}int Height(BST T){ /*返回当前节点的高度*/ if(T == NULL) return -1; else return T->bf;}int Max(int A, int B){ return ((A > B) ? A:B);}BST SingleRotateWithRight(BST K2){ /*RR型旋转*/ BST K1; K1 = K2->rchild; K2->rchild = K1->lchild; K1->lchild = K2; K2->bf = Max(Height(K2->lchild), Height(K2->rchild)) + 1; K1->bf = Max(Height(K1->lchild), Height(K1->rchild)) + 1; return K1;}BST SingleRotateWithLeft(BST K2){ /*LL型旋转*/ BST K1; K1 = K2->lchild; K2->lchild = K1->rchild; K1->rchild = K2; K2->bf = Max(Height(K2->lchild), Height(K2->rchild)) + 1; K1->bf = Max(Height(K1->lchild), Height(K1->rchild)) + 1; return K1;}BST DoubleRotateWithLeft(BST K3){ /*LR = RR(K3->lchild) + LL(K3)*/ K3->lchild = SingleRotateWithRight(K3->lchild); return SingleRotateWithLeft(K3);}BST DoubleRotateWithRight(BST K3){ /*LL = LL(K3->lchild) + RR(K3)*/ K3->rchild = SingleRotateWithLeft(K3->rchild); return SingleRotateWithRight(K3);}void OUT(BST T){ /*树的输出递归函数*/ if(T->lchild){ printf("Left\t%d\t[parent:%d]\n", T->lchild->data, T->data); OUT(T->lchild); } if(T->rchild){ printf("Right\t%d\t[parent:%d]\n", T->rchild->data, T->data); OUT(T->rchild); }}BST Rotate(BST T){ /*对于单个节点进行的AVL调整*/ if(Height(T->lchild) - Height(T->rchild) == 2){ if(Height(T->lchild->lchild) >= Height(T->lchild->rchild)){ T = SingleRotateWithLeft(T); } else{ T = DoubleRotateWithLeft(T); } } if(Height(T->rchild) - Height(T->lchild) ==2){ if(Height(T->rchild->rchild) >= Height(T->rchild->lchild)){ T = SingleRotateWithRight(T); } else{ T = DoubleRotateWithRight(T); } } return T;}BST AVLInsert(BST T){ /*AVL数的插入操作*/ if(T == NULL){ T = (BST)malloc(sizeof(struct node)); T->data = input; T->lchild = T->rchild = NULL; T->bf = 0; } else if(input < T->data){ T->lchild = AVLInsert(T->lchild); if(Height(T->lchild) - Height(T->rchild) == 2){ if(input < T->lchild->data){ T = SingleRotateWithLeft(T); /*LL旋转*/ } else{ T = DoubleRotateWithLeft(T); /*LR旋转*/ } } } else if(input > T->data){ T->rchild = AVLInsert(T->rchild); if(Height(T->rchild) - Height(T->lchild) == 2){ if(input > T->rchild->data){ T = SingleRotateWithRight(T); /*RR旋转*/ } else{ T = DoubleRotateWithRight(T); /*RL旋转*/ } } } T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1; return T;}void Output(BST T){ if(T == NULL){ printf("None\n"); } else{ printf("%d\troot\n", T->data); OUT(T); }}void Insert(){ printf("\nInput the point your want to Insert: "); scanf("%d", &input); R = AVLInsert(R); Output(R);}BST AVLDelete(BST T, int key){ if(T == NULL) return NULL; if(key == T->data){ if(T->rchild == NULL){ /*如果T得右儿子为空则直接删除*/ BST temp = T; T = T->lchild; free(temp); } else{ /*否则找到T->rchild的最左儿子代替T*/ BST temp = T->rchild; while(temp->lchild != NULL){ temp = temp->lchild; } T->data = temp->data; T->rchild = AVLDelete(T->rchild, temp->data); /*对于替代后的T及其各个子节点进行一些列调整,正到再次递归到T->rchild的最左儿子,删除它*/ T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1; } return T; } else if(key < T->data){ T->lchild = AVLDelete(T->lchild, key); } else{ T->rchild = AVLDelete(T->rchild, key); } T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1; if(T->lchild != NULL){ T->lchild = Rotate(T->lchild); } if(T->rchild != NULL){ T->rchild = Rotate(T->rchild); } T = Rotate(T); return T;}void Delete(){ printf("\nInput the point you want to Delete: "); scanf("%d", &input); R = AVLDelete(R, input); Output(R);}int main(){ while(1){ Chose(); switch(chos){ case 'i': Insert(); break; case 'd': Delete(); break; case 'e': exit(0); } } return 0;}
- (转)AVL树的插入_删除操作
- AVL树的插入_删除操作实现~
- AVL树的旋转,插入,删除操作
- AVL树的插入删除操作
- AVL树的插入与删除操作
- 数据结构-----AVL树的插入删除操作
- AVL树的插入、删除、查找操作
- AVL树的插入删除操作
- AVL的插入,删除操作
- AVL树_插入与删除
- avl树的插入操作和删除操作
- 二叉平衡树AVL插入删除操作的实现
- avl tree的插入删除操作代码
- AVL树的插入操作
- AVL树插入删除
- 平衡二叉查找树(AVL)的查找、插入、删除
- 平衡二叉查找树(AVL)的查找,插入,删除
- 平衡二叉树(AVL)的创建、插入、删除
- LINQ to ADO.NET
- VIM个人配置
- 2-SAT——1.0(hdu3062,poj3678)
- 浅析Java学习从入门到精通
- retain/copy/assign的含义
- (转)AVL树的插入_删除操作
- Spring Bean 注入 Servlet 的方法
- STM32之时钟树笔记
- POJ 1016 Numbers That Count
- validate和causesvalidation的区别1
- GetDlgItem使用
- EJB基础--JBoss服务器
- ubuntu切换用户root时认证失败
- 在Windows平台上测试程序的CPU使用率和内存占用量