16-1平衡树源代码
本例子分为3个文件。
类声明头文件 hAVL.h #ifndef AVLTREE_H_INCLUDED #define AVLTREE_H_INCLUDED //AVL树数据结构定义 typedef int ElementType;//AVL数节点包含数据类型 //树节点 typedef struct AVLNode{ ElementType element;//节点包含的数据元素 AVLNode *left;//节点左子树 AVLNode *right;//节点右子树 int height;//节点所在的高度 }*AVLTree; //AVL tree类封装 class CAVLTree{ private: //供内部调用的函数 int getHeight(AVLTree);//求得树的高度 void setHeight(AVLTree, int);//设置节点的高度值 //单旋转:向右旋转 AVLTree SingleRightRotate(AVLTree); //单旋转:向左旋转 AVLTree SingleLeftRotate(AVLTree); //双旋转:左右 AVLTree DoubleRightRotate(AVLTree); //双旋转:右左 AVLTree DoubleLeftRotate(AVLTree); public: //默认构造函数 CAVLTree(); //析构函数 ~CAVLTree(); //创建AVL树 void createAVLTree(ElementType *data, int n); //插入节点 AVLTree insertNode(AVLTree T, ElementType val); //删除树中元素值等于某值的节点 AVLTree deleteNode(AVLTree T, const ElementType val); //搜寻元素值等于某值的节点 AVLTree searchNode(AVLTree, ElementType); //前序遍历输出树 void preOrder(AVLTree T); //得到树中的元素值最大的节点 AVLTree getMaxNode(AVLTree); //得到树中的元素值最小的那个节点 AVLTree getMinNode(AVLTree); void deleteTree(AVLTree t); AVLTree T; }; #endif // AVLTREE_H_INCLUDED
//右右外侧插入导致的不平衡,采用单旋转-左旋转进行修正 //参数解释:类实现文件AVLTr.cpp #include "stdafx.h" #include "hAVL.h" #include <iostream> #include <cmath> #include <math.h> #include <cassert> using namespace std; int fmax(int i, int j) { return i>j?i:j; }; CAVLTree::CAVLTree() { T = NULL; } CAVLTree::~CAVLTree() { deleteTree(T); } //依据各元素的数据值,创建AVL树 void CAVLTree::createAVLTree(ElementType *data, int n) { if (T) { cout << "The AVL Tree has been created" << endl; return; } if (!n)//元素序列为空 { T = NULL; return; } for (int i = 0; i < n; ++i) { T = insertNode(T, *(data + i)); } return; } AVLTree CAVLTree::insertNode(AVLTree T, ElementType val) { AVLNode *pNewNode = new AVLNode; pNewNode->element = val; pNewNode->left = NULL; pNewNode->right = NULL; pNewNode->height = 1;//新节点一定被插入在空节点的位置 if (NULL == T) { T = pNewNode; return T; } //需要插入节点的树非空 //插入的元素已经存在于树中,不符合要求 if (val == T->element) { cout << "元素中有重复,构建AVL树失败!" << endl; return T; } //要插入的值小于根节点的值,将其插入左子树中 if (val < T->element) { //将其插入根节点的左子树中 T->left = insertNode(T->left, val); //判断平衡条件是否仍然满足 if (getHeight(T->left) - getHeight(T->right) > 1) { //分两种情况进行旋转操作 //插入点位于T的左子结点的左子树 if (val < T->left->element) //实施单旋转-右旋转 T = SingleRightRotate(T); else //插入点位于T的左子结点的右子树,实施双右旋转 T = DoubleRightRotate(T); } } //要插入的值大于根节点的值,将其插入右子树中 if (val > T->element) { T->right = insertNode(T->right, val); //判断平衡条件是否仍然满足 if (getHeight(T->right) - getHeight(T->left) > 1) { //节点插入到T的右子节点的右子树中 if (val > T->right->element) //实施单旋转-左旋转 T = SingleLeftRotate(T); else //节点插入到T的右子节点的左子树上 //实施双旋转-左旋转 T = DoubleLeftRotate(T); } } //更新节点的height值 setHeight(T, fmax(getHeight(T->left), getHeight(T->right)) + 1); return T; } AVLTree CAVLTree::deleteNode(AVLTree T, const ElementType val) { if (!T) { cout << "The tree is NULL, delete failed" << endl; return T; } AVLTree searchedNode = searchNode(T, val); //没有找到相应的节点,删除失败 if (!searchedNode) { cout << "Cann't find the node to delete " << val << endl; return T; } //找到了需要删除的节点 //需要删除的节点就是当前子树的根节点 if (val == T->element) { //左右子树都非空 if (T->left && T->right) { //在高度更大的那个子树上进行删除操作 if (getHeight(T->left) > getHeight(T->right)) { //左子树高度大,删除左子树中元素值最大的那个节点,同时将其值赋值给根节点 T->element = getMaxNode(T->left)->element; T->left = deleteNode(T->left, T->element); } else{ //删除右子树中元素值最小的那个节点,同时将其值赋值给根节点 T->element = getMinNode(T->right)->element; T->right = deleteNode(T->right, T->element); } } else{ //左右子树中有一个不为空,那个直接用需要被删除的节点的子节点替换之即可 AVLTree oldNode = T; T = (T->left ? T->left : T->right); delete oldNode;//释放节点所占的空间 oldNode = NULL; } } else if (val < T->element)//要删除的节点在左子树中 { //在左子树中进行递归删除 T->left = deleteNode(T->left, val); //判断是否仍然满足平衡条件 if (getHeight(T->right) - getHeight(T->left) > 1) { if (T->right->left > T->right->right) { //左双旋转 T = DoubleLeftRotate(T); } else//进行左单旋转 T = SingleLeftRotate(T); } else //满足平衡条件,需要更新高度信息 T->height = fmax(getHeight(T->left), getHeight(T->right)) + 1; } else//需要删除的节点在右子树中 { T->right = deleteNode(T->right, val); //判断是否满足平衡条件 if (getHeight(T->left) - getHeight(T->right) > 1) { if (getHeight(T->left->right) > getHeight(T->left->left)) //右双旋转 T = DoubleRightRotate(T); else //右单旋转 T = SingleRightRotate(T); } else //只需调整高度即可 T->height = fmax(getHeight(T->left), getHeight(T->right)) + 1; } return T; } AVLTree CAVLTree::searchNode(AVLTree T, ElementType val) { if (!T) { return NULL; } //搜索到 if (val == T->element) { return T; } else if (val < T->element) { //在左子树中搜索 return searchNode(T->left, val); } else { //在右子树中搜索 return searchNode(T->right, val); } } void CAVLTree::preOrder(AVLTree T) { if (!T) cout << "NULL "; else { cout << T->element << " "; preOrder(T->left); preOrder(T->right); } } AVLTree CAVLTree::getMaxNode(AVLTree T) { if (!T)//树为空 { return NULL; } AVLTree tempNode = T; //向右搜寻直至右子节点为NULL while (tempNode->right) { tempNode = tempNode->right; } return tempNode; } AVLTree CAVLTree::getMinNode(AVLTree T) { if (!T)//树为空 { return NULL; } AVLTree tempNode = T; //向左搜寻直至左子结点为NULL while (tempNode->left) { tempNode = tempNode->left; } return tempNode; } int CAVLTree::getHeight(AVLTree T) { return (T == NULL) ? 0 : (T->height); } void CAVLTree::setHeight(AVLTree T, int height) { T->height = height; } //左左外侧插入导致的不平衡,采用单旋转-右旋转进行修正 //参数解释: //T:指向因某种操作失去平衡的最小子树根节点 AVLTree CAVLTree::SingleRightRotate(AVLTree T) { AVLTree xPNode = T; AVLTree yPNode = T->left; xPNode->left = yPNode->right;//更改原根节点的左子树 yPNode->right = xPNode;//更改原根节点左孩子的右子树 //更新进行了旋转操作的节点的高度 xPNode->height = fmax(getHeight(xPNode->left), getHeight(xPNode->right)) + 1; yPNode->height = fmax(getHeight(yPNode->left), getHeight(yPNode->right)) + 1; //原根节点的左孩子节点成为新的根节点 return yPNode; //T:指向因某种操作失去平衡的最小子树根节点 AVLTree CAVLTree::SingleLeftRotate(AVLTree T) { AVLTree xPNode = T; AVLTree yPNode = T->right; xPNode->right = yPNode->left;//更改原根节点的右孩子 yPNode->left = xPNode;//提升原根节点的右孩子节点为新的根节点 //更新执行了旋转操作的节点的高度信息 xPNode->height = fmax(getHeight(xPNode->left), getHeight(xPNode->right)) + 1; yPNode->height = fmax(getHeight(yPNode->left), getHeight(yPNode->right)) + 1; //返回新的根节点 return yPNode; } //插入点位于T的左子结点的右子树 AVLTree CAVLTree::DoubleRightRotate(AVLTree T) { //双旋转可以通过两次单旋转实现 //第一次单旋转 assert(T->left != NULL); //对其左子树进行一次单旋转-左旋转 T->left = SingleLeftRotate(T->left); //第二次单旋转 //对新产生的树进行一次单旋转-右旋转 return SingleRightRotate(T); } //插入点位于T的右子节点的左子树 AVLTree CAVLTree::DoubleLeftRotate(AVLTree T) { //双旋转可以通过两次单旋转实现 //第一次单旋转 assert(T->right != NULL); //对其右子树进行一次单旋转-右旋转 T->right = SingleRightRotate(T->right); //第二次单旋转 //对新产生的树进行一次单旋转-左旋转 return SingleLeftRotate(T); } void CAVLTree::deleteTree(AVLTree t) { if (NULL == t) return; deleteTree(t->left); deleteTree(t->right); delete t; t = NULL; }
主函数文件 main.cpp // AVLTree.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" //平衡二叉树搜索树(AVL tree-Adelson-Velskii-Landis tree)编程实现 #include "hAVL.h" #include <iostream> using namespace std; int main() { // 通过给定序列创建平衡二叉树 const int NumElements = 8; cout << "AVL树各项操作编程实现:" << endl; int a[NumElements] = { 25,2,64,45,12,34,9,18}; CAVLTree *CAVLTreeObj1 = new CAVLTree(); CAVLTreeObj1->createAVLTree(a, NumElements); cout << "AVL Tree先序遍历结果:" << endl; CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl; // 插入一个新的数据 int insertedVal1 = 15; CAVLTreeObj1->T = CAVLTreeObj1->insertNode(CAVLTreeObj1->T, insertedVal1); cout << "向AVL树中插入元素 " << insertedVal1 << "之后的先序遍历结果:" << endl; CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl << endl; // 在插入一个新的数据(由重复数据情况下) int insertedVal2 = 16; CAVLTreeObj1->T = CAVLTreeObj1->insertNode(CAVLTreeObj1->T, insertedVal2); cout << "向AVL树中插入元素 " << insertedVal2 << "之后的先序遍历结果:" << endl; CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl << endl; // 寻找最小的元素 int minVal = CAVLTreeObj1->getMinNode(CAVLTreeObj1->T)->element; cout << "树中最小的元素是:" << minVal << endl; cout << endl; // 寻找最大的元素 int maxVal = CAVLTreeObj1->getMaxNode(CAVLTreeObj1->T)->element; cout << "树中最大的元素是:" << maxVal << endl; cout << endl; // 删除1个元素 const int deletedVal1 = 11; CAVLTreeObj1->T = CAVLTreeObj1->deleteNode(CAVLTreeObj1->T, deletedVal1); cout << "删除元素值为 " << deletedVal1 << "的节点之后的树先序遍历结果:" << endl; CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl << endl; // 删除第2个元素 const int deletedVal2 = 20; CAVLTreeObj1->T = CAVLTreeObj1->deleteNode(CAVLTreeObj1->T, deletedVal2); cout << "删除元素值为 " << deletedVal2 << "的节点之后的树先序遍历结果:" << endl; CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl << endl; // 删除第3个元素 const int deletedVal3 = 18; CAVLTreeObj1->T = CAVLTreeObj1->deleteNode(CAVLTreeObj1->T, deletedVal3); cout << "删除元素值为 " << deletedVal3 << "的节点之后的树先序遍历结果:" << endl; CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl << endl; const int searchedVal1 = 12; AVLTree searchedPNode = CAVLTreeObj1->searchNode(CAVLTreeObj1->T, searchedVal1); if (!searchedPNode) cout << "cannot find such node whose elemen equals " << searchedVal1 << endl; else cout << "search success element " << searchedVal1 << endl; const int searchedVal2 = 13; searchedPNode = CAVLTreeObj1->searchNode(CAVLTreeObj1->T, searchedVal2); if (!searchedPNode) cout << "cannot find such node whose elemen equals " << searchedVal2 << endl; else cout << "search success element " << searchedVal2 << endl; cout << endl << endl; getchar(); return 0; }