#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
平衡二叉树(AVL)
原文作者:venow
原文地址: https://www.cnblogs.com/venow/archive/2012/08/09/2629094.html
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://www.cnblogs.com/venow/archive/2012/08/09/2629094.html
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。