AVL树的创建、查找、删除节点、增加节点和释放内存的实现

include “stdafx.h”

include < iostream >

include < stdlib.h >

include < stdio.h>

include < vector>

include < assert.h>

using namespace std;

/*
平衡二叉树(Self-Balacing binary tree): 又称为“AVL树”,此AVL不同于AVL算法!!!以下简称为“AVL树”。
“AVL树”是“BST树(Binary Search Tree)”的演变版本,也就是“AVL树”也是BST树!!!

"AVL树"由于它任意节点的左右子树的深度差的绝对值小等于1,且权值左孩子<父节点<右孩子等的特性,使得其查询和增、删节点的时间复杂度都为O(log2n)。即即使在最差

的情况下,它的搜索和增、删节点的效率也能达到log2n!!!!

AVL树的规范要求:
    1. 左孩子<=父节点<=右孩子 (权值)
    2. 此树中的任意节点的左右子树的深度差的绝对值<=1

AVL树的创建:
    假设根节点为T增加一个节点a时:
    1. 先判断T是否存在,如果不存在,设T = a
    2. 将a先按BST树增加节点的方式增加
    3. 从增加节点的父节点开始,判断此树的的左右子树的深度差的绝对值是否<=1,若>1,则执行4步骤
    4. 通过“旋转”使该树重新达到平衡,旋转的次数为1次或多次!!设最开始出现不平衡的子树的根节点的root的旋转的种类有:
        a. 右旋(R):左子树的深度高于右子树时,且左子树以及其子树的节点全部都仅存在于左边,如60、50、40,此时向右旋转一次即平衡
        b. 左旋(L):右子树的深度高于左子树时,且右子树以及其子树的节点全部都仅存在于右边,如60、70、80,此时向左旋转一次即平衡
        c. 左右旋(LR):左子树的深度高于右子树时,且新增节点a在root的左孩子的右孩子上,如60、40、50,此时先向左旋转一次得60、50、40,再向右旋转一次即平衡
        d. 右左旋(RL):右子树的深度高于左子树时,且新增节点a在root的右孩子的左孩子上,如60、80、70,此时向右旋转一次得60、70、80,再向左旋转一次即平衡

AVL树删除节点:
    先找到需要删除的节点,再根据需要删除节点node有无孩子节点和在删除node后的左右孩子的深度以及node的左右孩子的深度来判断(参考函数void deleteNode(int value))
    1. 删除点为叶子节点
    2. 删除的节点有左孩子
    3. 删除的节点有右孩子
    4. 删除的节点左右孩子都有

*/

struct Tree
{
int value; //权值
Tree* pLeft; //记录左子树节点
Tree* pRight; //记录右子树节点
Tree* pParent; //记录父节点
Tree* pEqualValue; //记录相同值的节点

int leftDeep;   //记录左子树深度
int rightDeep;  //记录右子树深度

Tree(int n)
{
    value = n;
    pLeft = NULL;
    pRight = NULL;
    pParent = NULL;
    pEqualValue = NULL;
    leftDeep = 0;
    rightDeep = 0;
}

void AddEV(Tree* node)
{
    //默认将值相同的节点全部放于左孩子!!
    if (node == NULL)
    {
        return;
    }

    if (pEqualValue == NULL)
    {
        pEqualValue = node;
    }
    else
    {
        Tree* pTempNode = pEqualValue;
        while(pTempNode->pLeft)
        {
            pTempNode = pTempNode->pLeft;
        }

        pTempNode->pLeft = node;
        node->pParent = pTempNode;
    }
}

~Tree()
{
    cout << "释放内存: " << value << endl;
    pLeft = NULL;
    pRight = NULL;
    pParent = NULL;
    pEqualValue = NULL;
}

};

static vector< Tree*> m_rootTree;
static Tree* m_rootNode = NULL;

/*
Desc: 增加节点的深度
*/
void AddDeep(Tree* node)
{
Tree* pParent = node->pParent;
Tree* pChilde = node;
while (pParent != NULL)
{
if (pParent->pLeft == pChilde)
{
pParent->leftDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}
else if (pParent->pRight == pChilde)
{
pParent->rightDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}

    pChilde = pParent;
    pParent = pParent->pParent;
}

}

/*
Desc: 降低深度
*/
void subDeep(Tree* node)
{
Tree* pParent = node->pParent;
Tree* pChilde = node;
while (pParent != NULL)
{
if (pParent->pLeft == pChilde)
{
pParent->leftDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}
else if (pParent->pRight == pChilde)
{
pParent->rightDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}

    pChilde = pParent;
    pParent = pParent->pParent;
}

m_rootNode = pChilde;

}

/*
Desc: 右旋转
Param: node //要旋转的跟节点
*/
bool rotationRight(Tree* node)
{
Tree* c = node->pLeft;
Tree* b = c->pLeft;
Tree* a = node;

if ((a==NULL) || (b==NULL) || (c==NULL))
{
    //assert(a && b && c);
    return false;
}

Tree* tempRootNode = a->pParent;
c->pParent = tempRootNode;
if (tempRootNode != NULL)
{
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值