AVL树的旋转与插入操作

来源:互联网 发布:手机淘宝如何关联宝贝 编辑:程序博客网 时间:2024/05/19 05:04

AVL树是一种最原始的二叉查找树,它的各个节点的左右子树高度不超过1,因此能保证树的高度最大值为Olog(N),从而大大提高查找、插入、删除等操作的效率。在插入和删除元素时通过旋转操作使得AVL保持原有特性。本文给出了AVL树四种旋转操作和插入操作的C语言程序。

四种旋转操作参考《数据结构与算法分析——C语言描述第二版》。

插入操作则是在BST树查找函数框架的基础上进行改进,如果插入完成后AVL不再平衡,则根据条件进行旋转使树平衡。注意在旋转或插入完成后更新高度!本文中空节点高度设为-1。

#include<stdio.h>#include<stdlib.h>typedef struct AVLNode{int data;struct  AVLNode* lchild;struct  AVLNode* rchild;int height;//保存高度信息。} AVLNode, *AVLTree, *Position;int Height(Position T);int Max(int a, int b);Position SingleRotateWithLeft(Position k2);Position SingleRotateWithRight(Position k2);Position DoubleRotateWithLeft(Position k3);Position DoubleRotateWithRight(Position k3);AVLTree Insert(int data, AVLTree T);AVLTree Delete(int tar, AVLTree T);void ProOrderTraversal(AVLTree T);Position Find(int tar, AVLTree T);Position FindMin(AVLTree T);Position FindMax(AVLTree T);//测试数据来自《数据结构与算法分析——C语言描述》void main(){AVLTree T = NULL;T = Insert(3, T);T = Insert(2, T);T = Insert(1, T);printf("前序遍历结果为:");ProOrderTraversal(T);printf("\n");T = Insert(4, T);T = Insert(5, T);T = Insert(6, T);T = Insert(7, T);printf("前序遍历结果为:");ProOrderTraversal(T);printf("\n");T = Insert(16, T);T = Insert(15, T);T = Insert(14, T);T = Insert(13, T);T = Insert(12, T);T = Insert(11, T);T = Insert(10, T);T = Insert(8, T);T = Insert(9, T);printf("前序遍历结果为:");ProOrderTraversal(T);printf("\n");}int Height(Position T){if (!T)//空节点高度为-1return -1;elsereturn T->height;}int Max(int a, int b){return (a > b) ? a : b;}Position SingleRotateWithLeft(Position k2)//LL旋转{Position k1;k1 = k2->lchild;k2->lchild = k1->rchild;k1->rchild = k2;k2->height = Max(Height(k2->lchild), Height(k2->rchild)) + 1;//更新k2节点的高度!k1->height = Max(Height(k1->lchild), Height(k1->rchild)) + 1;//更新k1节点的高度!return k1;}Position SingleRotateWithRight(Position k2)//RR旋转{Position k1;k1 = k2->rchild;k2->rchild = k1->lchild;k1->lchild = k2;k2->height = Max(Height(k2->lchild), Height(k2->rchild)) + 1;//更新k2节点的高度!k1->height = Max(Height(k1->lchild), k2->height) + 1;//更新k1节点的高度!return k1;}Position DoubleRotateWithLeft(Position k3)//LR旋转{k3->lchild = SingleRotateWithRight(k3->lchild);return SingleRotateWithLeft(k3);}Position DoubleRotateWithRight(Position k3)//RL旋转{k3->rchild = SingleRotateWithLeft(k3->rchild);return SingleRotateWithRight(k3);}AVLTree Insert(int data, AVLTree T){if (!T)//找到插入位置,进行插入{T = (AVLTree)malloc(sizeof(AVLNode));T->data = data;T->height = 0;T->lchild = T->rchild = NULL;}else if (data < T->data)//进行左子树递归插入{T->lchild = Insert(data, T->lchild);if (Height(T->lchild) - Height(T->rchild) == 2){if (data < T->lchild->data)T = SingleRotateWithLeft(T);elseT = DoubleRotateWithLeft(T);}}else if (data > T->data)//进行右子树递归插入{T->rchild = Insert(data, T->rchild);if (Height(T->lchild) - Height(T->rchild) == -2){if (data > T->rchild->data)T = SingleRotateWithRight(T);elseT = DoubleRotateWithRight(T);}}else//插入失败printf("AVL树已有该元素,插入失败");T->height = Max(Height(T->lchild), Height(T->rchild)) + 1;  //更新树的高度!  return T;}void ProOrderTraversal(AVLTree T){if (T){printf("%d ", T->data);ProOrderTraversal(T->lchild);ProOrderTraversal(T->rchild);}}Position Find(int tar, AVLTree T){if (!T)return NULL;else if (tar < T->data)return Find(tar, T->lchild);else if (tar > T->data)return Find(tar, T->rchild);elsereturn T;}Position FindMin(AVLTree T){if (!T)return NULL;else if (!T->lchild)return T;elsereturn FindMin(T->lchild);}Position FindMax(AVLTree T){if (T){while (T && T->rchild)T = T->rchild;}return T;}


原创粉丝点击