zoukankan      html  css  js  c++  java
  • 平衡二叉树(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
  • 相关阅读:
    vs2015连接oracle 11g(.net自带方式 using System.Data.OracleClient;)
    div层叠顺序额
    linux运维、架构之路-Zabbix自动化
    linux运维、架构之路-Zabbix监控
    linux运维、架构之路-keepalived高可用
    linux运维、架构之路-内网NTP时间服务器
    linux运维、架构之路-Nginx反向代理
    linux运维、架构之路-数据库迁移
    linux运维、架构之路-网络基础
    linux运维、架构之路-shell编程(一)
  • 原文地址:https://www.cnblogs.com/venow/p/2629094.html
Copyright © 2011-2022 走看看