平衡二叉树(AVL)

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <stack>
#include <queue>
#include <Windows.h>
using namespace std;

typedef struct _Node
{
    int data;
    struct _Node *left;
    struct _Node *right;
    int bf;              //平衡因子
    _Node()
    {
        data = 0;
        left = NULL;
        right = NULL;
        bf = 0;
    }
}Node, *_PNode;

//******************************************AVL**********************************************begin

//参考 维基百科 AVL : http://zh.wikipedia.org/wiki/AVL%E6%A0%91
//                  http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html

//右旋
_PNode AVLLLTree(_PNode pNode)
{
    _PNode pNewNode = pNode->left;
    pNode->left = pNewNode->right;
    pNewNode->right = pNode;
    if (pNewNode->bf == 1)
    {
        pNode->bf = 0;
        pNewNode->bf = 0;
    }
    else
    {
        pNode->bf = 1;
        pNewNode->bf = -1;
    }
    return pNewNode;
}

//左旋
_PNode AVLRRTree(_PNode pNode)
{
    _PNode pNewNode = pNode->right;
    pNode->right = pNewNode->left;
    pNewNode->left = pNode;
    if (pNewNode->bf == -1)
    {
        pNode->bf = 0;
        pNewNode->bf = 0;
    }
    else
    {
        pNode->bf = -1;
        pNewNode->bf = 1;
    }
    return pNewNode;
}

//先右旋再左旋
_PNode AVLLRTree(_PNode pNode)
{
    _PNode pLeft = pNode->left;
    _PNode pNewNode = pLeft->right;
    pLeft->right = pNewNode->left;
    pNode->left = pNewNode->right;
    pNewNode->left = pLeft;
    pNewNode->right = pNode;
    switch (pNewNode->bf )
    {
    case 1:
        pLeft->bf = 0;
        pNode->bf = -1;
        break;
    case -1:
        pLeft->bf = 1;
        pNode->bf = 0;
        break;
    }
    pNewNode->bf = 0;
    return pNewNode;
}

//先左旋再右旋
_PNode AVLRLTree(_PNode pNode)
{
    _PNode pRight = pNode->right;
    _PNode pNewNode = pRight->left;
    pRight->left = pNewNode->right;
    pNode->right = pNewNode->left;
    pNewNode->left = pNode;
    pNewNode->right = pRight;
    switch (pNewNode->bf)
    {
    case 1:
        pNode->bf = 0;
        pRight->bf = -1;
        break;
    case -1:
        pNode->bf = 1;
        pRight->bf = 0;
        break;
    }
    pNewNode->bf = 0;
    return pNewNode;
}
_PNode pAvlRoot
= NULL; //AVL的根节点 stack<_PNode> sAvl; //保存从根节点到插入点的路径节点 bool AVLRotateTree(_PNode pNode, int bf) { bool bTallChange = true; _PNode pChild; _PNode pNewNode; if (2 == bf) { pChild = pNode->left; if (1 == pChild->bf) { pNewNode = AVLLLTree(pNode); } else if (-1 == pChild->bf) { pNewNode = AVLLRTree(pNode); } else { pNewNode = AVLLLTree(pNode); bTallChange = false; } } else if (-2 == bf) { pChild = pNode->right; if (1 == pChild->bf) { pNewNode = AVLRLTree(pNode); } else if (-1 == pChild->bf) { pNewNode = AVLRRTree(pNode); } else { pNewNode = AVLRRTree(pNode); bTallChange = false; } } if (!sAvl.empty()) { _PNode pParent = sAvl.top(); if (pParent->data > pNewNode->data) { pParent->left = pNewNode; } else if (pParent->data < pNewNode->data) { pParent->right = pNewNode; } } else { pAvlRoot = pNewNode; } return bTallChange; } //插入节点 void AVLInsertNode(int key) { if (BSTSearch(pAvlRoot, key)) //找到,不能插入直接返回 { return; } _PNode pNode = new Node; pNode->data = key; if (NULL == pAvlRoot) { pAvlRoot = pNode; return; } while (!sAvl.empty()) //清空栈 { sAvl.pop(); } _PNode p = pAvlRoot; while (NULL != p) { sAvl.push(p); if (key < p->data) { p = p->left; } else if (key > p->data) { p = p->right; } } _PNode pre = sAvl.top(); if (key < pre->data) { pre->left = pNode; } else if (key > pre->data) { pre->right = pNode; } int bf; while (!sAvl.empty()) { pre = sAvl.top(); sAvl.pop(); bf = (pre->data > key) ? 1 : -1; pre->bf += bf; bf = pre->bf; if (bf == 0) { break; } else if (2 == bf || -2 == bf) { AVLRotateTree(pre, bf); break; } } } //删除节点 void AVLRemoveNode(int key) { _PNode pNode = pAvlRoot; while (!sAvl.empty()) { sAvl.pop(); } while (NULL != pNode) { if (key < pNode->data) { sAvl.push(pNode); pNode = pNode->left; } else if (key > pNode->data) { sAvl.push(pNode); pNode = pNode->right; } else { _PNode pPreNode = sAvl.top(); if (NULL == pNode->left || NULL == pNode->right) //3、该节点只有一条子树 { if (NULL != pNode->left) { if (pNode == pAvlRoot) { pAvlRoot = pNode->left; } else if (pPreNode->left == pNode) { pPreNode->left = pNode->left; } else { pPreNode->right = pNode->left; } } else { if (pNode == pAvlRoot) { pAvlRoot = pNode->right; } else if (pPreNode->left == pNode) { pPreNode->left = pNode->right; } else { pPreNode->right = pNode->right; } } } else //4、该节点有左右子树 { _PNode pPre = pNode; sAvl.push(pNode); _PNode pSearch = pNode->right; while (NULL != pSearch->left) //5、找该节点右子树的最小值,即真正删除的点 { sAvl.push(pSearch); pPre = pSearch; pSearch = pSearch->left; } sAvl.pop(); //删除的点没用,将删除的点弹栈 pNode->data = pSearch->data; if (pPre->left == pSearch) { pPre->left = pSearch->right; } else { pPre->right = pSearch->right; } } int bf; while (!sAvl.empty()) { pPreNode = sAvl.top(); sAvl.pop(); bf = (pPreNode->data > key) ? -1 : 1; pPreNode->bf += bf; bf = pPreNode->bf; if (0 != bf) { if (1 == bf || -1 == bf || !AVLRotateTree(pPreNode, bf)) { break; } } } break; } } } //******************************************AVL***********************************************end
    原文作者:venow
    原文地址: https://www.cnblogs.com/venow/archive/2012/08/09/2629094.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞