极客 - 博文29 - AVL树的平衡问题

来源:互联网 发布:一起走数据怎么作弊 编辑:程序博客网 时间:2024/05/16 15:57
*程序名称:  AVL树的平衡问题
*作者: 田鑫  
*完成日期: 2016 - 10 - 27 
*版本号: v1.0 
*平台: vs2015
*问题描述: AVL树的平衡问题, 如果不支持最新C标准, 将scanf_s改为scanf
#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define SIZE 15typedef int elemType;typedef struct avlTree{int height;elemType data;struct avlTree *left;struct avlTree *right;}AvlTree;typedef AvlTree * PAvlTree;void preOrder(PAvlTree T);void midOrder(PAvlTree T);void posOrder(PAvlTree T);void leveOrder(PAvlTree T);static int height(PAvlTree T);PAvlTree makeEmpty(PAvlTree T);PAvlTree insert(PAvlTree T, elemType x);PAvlTree singleRotateWithLeft(PAvlTree T);PAvlTree singleRotateWithRight(PAvlTree T);PAvlTree doubleRotateWithLeft(PAvlTree T);PAvlTree doubleRotateWithRight(PAvlTree T);int findMax(int leftHeight, int rightHeight);int main(void){int i = 1;int test = 0;PAvlTree T = NULL;scanf_s("%d", &test);while ((test != -1) && (i != SIZE)){T = insert(T, test);scanf_s("%d", &test);i++;}printf("\n");/*********前序遍历*********/printf("前序遍历:"); preOrder(T);printf("\n\n");/*********中序遍历*********/printf("中序遍历:");midOrder(T);printf("\n\n");/*********后序遍历*********/printf("后序遍历:");posOrder(T);printf("\n\n");/*********层次遍历*********/printf("层次遍历:");leveOrder(T);printf("\n\n\n");system("pause");return 0;}void preOrder(PAvlTree T){if (T){printf("%4d", T->data);preOrder(T->left);preOrder(T->right);}}void midOrder(PAvlTree T){if (T){midOrder(T->left);printf("%4d", T->data);midOrder(T->right);}}void posOrder(PAvlTree T){if (T){posOrder(T->left);posOrder(T->right);printf("%4d", T->data);}}void leveOrder(PAvlTree T){PAvlTree tree[SIZE];int front = -1, rear = 0;//指针下标if (!T)//空栈直接退出 {printf("Tree is empty!\n");return;}tree[rear] = T;//记录当前地址 while (front != rear)//当front等于rear则队列为空 {front++;printf("%4d", tree[front]->data);if (tree[front]->left)//左子树不为空入栈{rear++;tree[rear] = tree[front]->left;}if (tree[front]->right)//右子树不为空入栈{rear++;tree[rear] = tree[front]->right;}}}static int height(PAvlTree T){if (!T){return -1;}else{return T->height;}}PAvlTree makeEmpty(PAvlTree T) {if (T){makeEmpty(T->left);makeEmpty(T->right);free(T);}return NULL;}PAvlTree insert(PAvlTree T, elemType x){if (!T){T = (PAvlTree)malloc(sizeof(AvlTree));if (!T){printf("创建失败!\n");exit(1);}else{T->data = x;T->height = 0;T->left = T->right = NULL;}}else if (x < T->data){T->left = insert(T->left, x);if (height(T->left) - height(T->right) == 2){if (x < T->left->data){T = singleRotateWithLeft(T);}else{T = doubleRotateWithLeft(T);}}}else if (x > T->data){T->right = insert(T->right, x);if (height(T->right) - height(T->left) == 2){if (x > T->right->data){T = singleRotateWithRight(T);}else{T = doubleRotateWithRight(T);}}}T->height = findMax(height(T->left), height(T->right)) + 1;return T;}/**功能: 平衡根左子树引起的AVL树不平衡*参数: 树的根的地址*返回值: 进行AVL平衡单旋转后的根地址*易错点: 要先计算树根子树的高度最后再计算树根的高度*/PAvlTree singleRotateWithLeft(PAvlTree T){PAvlTree Pt;Pt = T->left;T->left = Pt->right;Pt->right = T;T->height = findMax(height(T->left), height(T->right)) + 1;Pt->height = findMax(height(Pt->left), height(Pt->right)) + 1;return Pt;}/**功能: 平衡根右子树引起的AVL树不平衡*参数: 树的根的地址*返回值: 进行AVL平衡单旋转后的根地址*易错点: 要先计算树根子树的高度最后再计算树根的高度*/PAvlTree singleRotateWithRight(PAvlTree T){PAvlTree Pt;Pt = T->right;T->right = Pt->left;Pt->left = T;T->height = findMax(height(T->left), height(T->right)) + 1;Pt->height = findMax(height(Pt->left), height(Pt->right)) + 1;return Pt;}/**功能: 平衡根的左子树的右子树引起的AVL树不平衡*参数: 树的根的地址*返回值: 进行AVL平衡双旋转后的根地址*易错点: 要先计算树根的左右子树的高度最后再计算树根的高度*/PAvlTree doubleRotateWithLeft(PAvlTree T){PAvlTree k1, k2;k1 = T->left;k2 = k1->right;k1->right = k2->left;k2->left = k1;T->left = k2->right;k2->right = T;k1->height = findMax(height(k1->left), height(k1->right)) + 1;T->height = findMax(height(T->left), height(T->right)) + 1;k2->height = findMax(height(k2->left), height(k2->right)) + 1;return k2;}/**功能: 平衡根的右子树的左子树引起的AVL树不平衡*参数: 树的根的地址*返回值: 进行AVL平衡双旋转后的根地址*易错点: 要先计算树根的左右子树的高度最后再计算树根的高度*/PAvlTree doubleRotateWithRight(PAvlTree T){PAvlTree k1, k2;k1 = T->right;k2 = k1->left;k1->left = k2->right;k2->right = k1;T->right = k2->left;k2->left = T;k1->height = findMax(height(k1->left), height(k1->right)) + 1;T->height = findMax(height(T->left), height(T->right)) + 1;k2->height = findMax(height(k2->left), height(k2->right)) + 1;return k2;}int findMax(int leftHeight, int rightHeight){return (leftHeight > rightHeight) ? leftHeight : rightHeight;}

运行结果:


1 0