zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    泛型总结
    Java多线程(学习篇)
    Java线程:总结
    Java线程:线程交互
    Java线程:线程安全类和Callable与Future(有返回值的线程)
    Java线程:条件变量、原子量、线程池等
    Java线程:堵塞队列与堵塞栈
    Java线程:锁
    poj 1679 The Unique MST(唯一的最小生成树)
    poj 1659 Frogs' Neighborhood (DFS)
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/8509131.html
Copyright © 2011-2022 走看看