├── result.png ├── BalanceTree ├── Tree.h ├── stdafx.h ├── TestTree.cpp ├── stdafx.cpp ├── targetver.h ├── StlSet.h ├── StlSet.cpp ├── BSTree.h ├── RBTree.h ├── AVLTree.h ├── BSTree2.h ├── RBTree3.h ├── AVLTree2.h ├── RBTree2.h ├── TreeNode.h ├── ReadMe.txt ├── TreeNode.cpp ├── BalanceTree.vcxproj.filters ├── Tree.cpp ├── BalanceTree.vcproj ├── BSTree2.cpp ├── BSTree.cpp ├── AVLTree2.cpp ├── BalanceTree.vcxproj ├── AVLTree.cpp ├── RBTree.cpp ├── RBTree3.cpp └── RBTree2.cpp ├── Document ├── RBT 插入.jpg ├── RBT 删除逻辑.jpg ├── AVL 平衡因子 增删.png ├── AVL 平衡因子 增删手稿.jpg ├── RBT 删除逻辑 二次调平.jpg ├── AVL 平衡因子 删除(m为0).png ├── AVL 平衡因子 删除(m=0)手稿.jpg └── 红黑树(Red Black Tree) - Uncle_Bjorney.pdf ├── BalanceTree(vs2008).sln ├── BalanceTree.sln └── README.md /result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/result.png -------------------------------------------------------------------------------- /BalanceTree/Tree.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/BalanceTree/Tree.h -------------------------------------------------------------------------------- /Document/RBT 插入.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/RBT 插入.jpg -------------------------------------------------------------------------------- /BalanceTree/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/BalanceTree/stdafx.h -------------------------------------------------------------------------------- /Document/RBT 删除逻辑.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/RBT 删除逻辑.jpg -------------------------------------------------------------------------------- /BalanceTree/TestTree.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/BalanceTree/TestTree.cpp -------------------------------------------------------------------------------- /BalanceTree/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/BalanceTree/stdafx.cpp -------------------------------------------------------------------------------- /BalanceTree/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/BalanceTree/targetver.h -------------------------------------------------------------------------------- /Document/AVL 平衡因子 增删.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/AVL 平衡因子 增删.png -------------------------------------------------------------------------------- /Document/AVL 平衡因子 增删手稿.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/AVL 平衡因子 增删手稿.jpg -------------------------------------------------------------------------------- /Document/RBT 删除逻辑 二次调平.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/RBT 删除逻辑 二次调平.jpg -------------------------------------------------------------------------------- /Document/AVL 平衡因子 删除(m为0).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/AVL 平衡因子 删除(m为0).png -------------------------------------------------------------------------------- /Document/AVL 平衡因子 删除(m=0)手稿.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/AVL 平衡因子 删除(m=0)手稿.jpg -------------------------------------------------------------------------------- /Document/红黑树(Red Black Tree) - Uncle_Bjorney.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicaril/BalanceTree/HEAD/Document/红黑树(Red Black Tree) - Uncle_Bjorney.pdf -------------------------------------------------------------------------------- /BalanceTree/StlSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tree.h" 3 | #include 4 | using namespace std; 5 | 6 | class StlSet : 7 | public Tree 8 | { 9 | public: 10 | StlSet(void); 11 | virtual ~StlSet(void); 12 | 13 | bool Insert(T& Data); 14 | bool Delete(T& Data); 15 | 16 | bool Check(){return true;} 17 | char* GetTreeName(){return "Stl Set";} 18 | 19 | private: 20 | set Obj; 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /BalanceTree/StlSet.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "StlSet.h" 3 | 4 | 5 | StlSet::StlSet(void) 6 | { 7 | } 8 | 9 | 10 | StlSet::~StlSet(void) 11 | { 12 | } 13 | 14 | bool StlSet::Insert(T& Data) 15 | { 16 | Obj.insert( Data ); 17 | return true; 18 | } 19 | 20 | bool StlSet::Delete(T& Data) 21 | { 22 | set::iterator it = Obj.find(Data); 23 | if ( it != Obj.end() ) 24 | { 25 | Obj.erase( it ); 26 | return true; 27 | } 28 | return false; 29 | } 30 | -------------------------------------------------------------------------------- /BalanceTree/BSTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Tree.h" 3 | 4 | class BSTree : public Tree 5 | { 6 | public: 7 | BSTree(void); 8 | virtual ~BSTree(void); 9 | 10 | bool Insert(T& Data); 11 | bool Delete(T& Data); 12 | 13 | bool Check(); 14 | char* GetTreeName(){return "BS Tree";} 15 | 16 | public: 17 | 18 | TreeNode * SingleRotateWithLeft(TreeNode * Node); 19 | TreeNode * DoubleRotateWithLeft(TreeNode * Node); 20 | TreeNode * SingleRotateWithRight(TreeNode * Node); 21 | TreeNode * DoubleRotateWithRight(TreeNode * Node); 22 | 23 | private: 24 | 25 | bool CheckNode(TreeNode * Node,PF_Show pfShow); 26 | bool _Check(TreeNode * Node,PF_Show pfShow); 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /BalanceTree/RBTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tree.h" 3 | 4 | class RBTree : 5 | public Tree 6 | { 7 | public: 8 | RBTree(void); 9 | virtual ~RBTree(void); 10 | 11 | bool Insert(T& Data); 12 | bool Delete(T& Data); 13 | 14 | bool Check(); 15 | char* GetTreeName(){return "RB Tree";} 16 | 17 | private: 18 | 19 | TreeNode* SingleRotateWithLeft(TreeNode * Node); 20 | TreeNode* DoubleRotateWithLeft(TreeNode * Node); 21 | TreeNode* SingleRotateWithRight(TreeNode * Node); 22 | TreeNode* DoubleRotateWithRight(TreeNode * Node); 23 | 24 | private: 25 | 26 | int GetBlackNodeLeft(TreeNode * Node); 27 | int GetBlackNodeRight(TreeNode * Node); 28 | bool _Check(TreeNode * Node); 29 | 30 | 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /BalanceTree/AVLTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tree.h" 3 | 4 | class AVLTree : 5 | public Tree 6 | { 7 | public: 8 | AVLTree(void); 9 | ~AVLTree(void); 10 | 11 | bool Insert(T& Data); 12 | bool Delete(T& Data); 13 | 14 | bool Check(); 15 | char* GetTreeName(){return "AVL Tree";} 16 | 17 | private: 18 | 19 | TreeNode * BalanceRotateWithLeft(TreeNode * Node); 20 | TreeNode * BalanceRotateWithRight(TreeNode * Node); 21 | 22 | TreeNode * SingleRotateWithLeft(TreeNode* Node); 23 | TreeNode * DoubleRotateWithLeft(TreeNode* Node); 24 | TreeNode * SingleRotateWithRight(TreeNode* Node); 25 | TreeNode * DoubleRotateWithRight(TreeNode* Node); 26 | 27 | private: 28 | bool CheckNode(TreeNode * Node,PF_Show pfShow); 29 | bool _Check(TreeNode * Node,PF_Show pfShow); 30 | 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /BalanceTree/BSTree2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Tree.h" 3 | 4 | class BSTree2 : 5 | public Tree 6 | { 7 | public: 8 | BSTree2(void); 9 | virtual ~BSTree2(void); 10 | 11 | public: 12 | bool Insert(T& Data); 13 | bool Delete(T& Data); 14 | bool Check(); 15 | 16 | char* GetTreeName(){return "BS Recursion";} 17 | 18 | private: 19 | bool _Insert( TreeNode ** Node, T& Data, bool * bSign); 20 | bool _Delete( TreeNode ** Node, T& Data, bool * bSign); 21 | 22 | TreeNode* SingleRotateWithLeft(TreeNode * Node); 23 | TreeNode* SingleRotateWithRight(TreeNode * Node); 24 | TreeNode* DoubleRotateWithLeft(TreeNode * Node); 25 | TreeNode* DoubleRotateWithRight(TreeNode * Node); 26 | 27 | private: 28 | 29 | bool CheckNode(TreeNode * Node,PF_Show pfShow); 30 | bool _Check(TreeNode * Node,PF_Show pfShow); 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /BalanceTree/RBTree3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tree.h" 3 | class RBTree3 : 4 | public Tree 5 | { 6 | public: 7 | RBTree3(void); 8 | virtual ~RBTree3(void); 9 | 10 | bool Insert(T& Data); 11 | bool Delete(T& Data); 12 | 13 | bool Check(); 14 | char* GetTreeName(){return "RB Recursion3";} 15 | 16 | private: 17 | bool _Insert(TreeNode ** Node, T& Data, bool * bSign); 18 | bool _Delete(TreeNode ** Node, T& Data, bool * bSign); 19 | 20 | TreeNode * FixBlackTreeWithLeft(TreeNode * Node); 21 | TreeNode * FixBlackTreeWithRight(TreeNode * Node); 22 | 23 | TreeNode* SingleRotateWithLeft(TreeNode * Node); 24 | TreeNode* SingleRotateWithRight(TreeNode * Node); 25 | TreeNode* DoubleRotateWithLeft(TreeNode * Node); 26 | TreeNode* DoubleRotateWithRight(TreeNode * Node); 27 | 28 | private: 29 | 30 | int GetBlackNodeLeft(TreeNode * Node); 31 | int GetBlackNodeRight(TreeNode * Node); 32 | bool _Check(TreeNode * Node); 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /BalanceTree/AVLTree2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tree.h" 3 | 4 | class AVLTree2 : 5 | public Tree 6 | { 7 | public: 8 | AVLTree2(void); 9 | virtual ~AVLTree2(void); 10 | 11 | bool Insert(T& Data); 12 | bool Delete(T& Data); 13 | 14 | bool Check(); 15 | char* GetTreeName(){return "AVL Recursion";} 16 | 17 | private: 18 | 19 | bool _Insert(TreeNode ** ppNode, T& Data, bool * bSign); 20 | bool _Delete(TreeNode ** ppNode, T& Data, bool * bSign); 21 | 22 | private: 23 | 24 | TreeNode * BalanceRotateWithLeft(TreeNode * Node); 25 | TreeNode * BalanceRotateWithRight(TreeNode * Node); 26 | 27 | TreeNode * SingleRotateWithLeft(TreeNode* Node); 28 | TreeNode * DoubleRotateWithLeft(TreeNode* Node); 29 | TreeNode * SingleRotateWithRight(TreeNode* Node); 30 | TreeNode * DoubleRotateWithRight(TreeNode* Node); 31 | 32 | private: 33 | bool CheckNode(TreeNode * Node,PF_Show pfShow); 34 | bool _Check(TreeNode * Node,PF_Show pfShow); 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /BalanceTree/RBTree2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tree.h" 3 | class RBTree2 : 4 | public Tree 5 | { 6 | public: 7 | RBTree2(void); 8 | virtual ~RBTree2(void); 9 | 10 | bool Insert(T& Data); 11 | bool Delete(T& Data); 12 | 13 | bool Check(); 14 | char* GetTreeName(){return "RB Recursion2";} 15 | 16 | private: 17 | bool _Insert(TreeNode ** Node, T& Data, bool * bSign); 18 | bool _Delete(TreeNode ** Node, T& Data, bool * bSign); 19 | 20 | TreeNode * FixRotateWithLeft(TreeNode ** pNode, bool * sSign); 21 | TreeNode * FixRotateWithRight(TreeNode ** pNode, bool * sSign); 22 | 23 | TreeNode* SingleRotateWithLeft(TreeNode * Node); 24 | TreeNode* SingleRotateWithRight(TreeNode * Node); 25 | TreeNode* DoubleRotateWithLeft(TreeNode * Node); 26 | TreeNode* DoubleRotateWithRight(TreeNode * Node); 27 | 28 | private: 29 | 30 | int GetBlackNodeLeft(TreeNode * Node); 31 | int GetBlackNodeRight(TreeNode * Node); 32 | bool _Check(TreeNode * Node); 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /BalanceTree(vs2008).sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BalanceTree", "BalanceTree\BalanceTree.vcproj", "{017D4ECB-57AF-44F8-9280-07F53288A9E6}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {017D4ECB-57AF-44F8-9280-07F53288A9E6}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {017D4ECB-57AF-44F8-9280-07F53288A9E6}.Debug|Win32.Build.0 = Debug|Win32 14 | {017D4ECB-57AF-44F8-9280-07F53288A9E6}.Release|Win32.ActiveCfg = Release|Win32 15 | {017D4ECB-57AF-44F8-9280-07F53288A9E6}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /BalanceTree/TreeNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef int T; 4 | typedef void (PF_Show)(T& Data); 5 | typedef void (PF_Show2)(T& Data, int nSign); 6 | 7 | #define NS_RED 0 8 | #define NS_BLACK 1 9 | 10 | class TreeNode 11 | { 12 | public: 13 | TreeNode(void); 14 | TreeNode(T& Data); 15 | ~TreeNode(void); 16 | 17 | void Init(); 18 | void Release(); 19 | 20 | public: 21 | int Height(); 22 | int FixHeight(); 23 | 24 | public: 25 | T m_Data; 26 | TreeNode * m_lchild; 27 | TreeNode * m_rchild; 28 | TreeNode * m_parent; 29 | union{ 30 | int m_height; 31 | int m_bf; 32 | int m_color; 33 | int m_sign; 34 | }u; 35 | }; 36 | 37 | int GetNodeHeightDeep(TreeNode * Node); 38 | 39 | bool IsLeftRed(TreeNode * Node); 40 | bool IsRightRed(TreeNode * Node); 41 | void SwapColor(TreeNode * Node); 42 | 43 | // bool IsLeftRed(TreeNode * Node); 44 | // bool IsRightRed(TreeNode * Node); 45 | 46 | void Show(T& Data); 47 | void Show2(T& Data, int nSign); 48 | void ShowError(T& Data); 49 | -------------------------------------------------------------------------------- /BalanceTree/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | 控制台应用程序:TestTree 项目概述 3 | ======================================================================== 4 | 5 | 应用程序向导已为您创建了此 TestTree 应用程序。 6 | 7 | 本文件概要介绍组成 TestTree 应用程序的每个文件的内容。 8 | 9 | 10 | TestTree.vcxproj 11 | 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 12 | 13 | TestTree.vcxproj.filters 14 | 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 15 | 16 | TestTree.cpp 17 | 这是主应用程序源文件。 18 | 19 | ///////////////////////////////////////////////////////////////////////////// 20 | 其他标准文件: 21 | 22 | StdAfx.h, StdAfx.cpp 23 | 这些文件用于生成名为 TestTree.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 24 | 25 | ///////////////////////////////////////////////////////////////////////////// 26 | 其他注释: 27 | 28 | 应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 29 | 30 | ///////////////////////////////////////////////////////////////////////////// 31 | -------------------------------------------------------------------------------- /BalanceTree.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BalanceTree", "BalanceTree\BalanceTree.vcxproj", "{BD527E87-7B5F-4416-8E7F-E53E35D422C4}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Debug|Win32.Build.0 = Debug|Win32 16 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Debug|x64.ActiveCfg = Debug|x64 17 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Debug|x64.Build.0 = Debug|x64 18 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Release|Win32.ActiveCfg = Release|Win32 19 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Release|Win32.Build.0 = Release|Win32 20 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Release|x64.ActiveCfg = Release|x64 21 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BalanceTree 2 | 3 | 本项目为平衡树的性能对比C++测试工程,非调用第三方库,包括: 4 | 1. AVL 基于节点高度差的增删逻辑,c++递归实现。 5 | 2. AVL 基于节点高度差的增删逻辑,c++非递归实现。 6 | 3. AVL 基于节点平衡因子的增删逻辑,c++递归实现。 7 | 4. AVL 基于节点平衡因子的增删逻辑,c++非递归实现。 8 | 5. RBT 红黑树的增删逻辑,包含C++多种递归删除方案的实现。 9 | 6. RBT 红黑树的增删逻辑,C++非递归的实现。 10 | 7. 各平衡树的校验逻辑,及性能测试。 11 | 8. 结论:顺序插入1000w数值,该代码中AVL增删速度要优于红黑树、STL::Set 12 | 13 | # BalanceTree 14 | This project is a C++ test project for the performance comparison of balanced tree, which does not call third-party libraries, including: 15 | 1. AVL based on node height difference of addition and deletion logic, c++ recursive implementation. 16 | 2. AVL based on the node height difference of addition and deletion logic, c++ non-recursive implementation. 17 | 3. AVL based on node balance factor add and delete logic, c++ recursive implementation. 18 | 4. AVL based on node balance factor add and delete logic, c++ non-recursive implementation. 19 | 5. RBT red black tree addition and deletion logic, including C++ a variety of recursive deletion scheme implementation. 20 | 6. RBT red black tree addition and deletion logic, C++ non-recursive implementation. 21 | 7. Verification logic of each balance tree and performance test. 22 | 8. Conclusion: With sequential insertion of 1000w values, AVL in this code is faster than red-black tree and STL::Set 23 | 24 | # Video 25 | 对应的视频教程:https://space.bilibili.com/1700469421 26 | 27 | ## Screenshots 28 | 29 | 30 | ## AVL 31 | 32 | 33 | 34 | ## RBTree 35 | 36 | -------------------------------------------------------------------------------- /BalanceTree/TreeNode.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "TreeNode.h" 3 | 4 | TreeNode::TreeNode(void) 5 | { 6 | Init(); 7 | } 8 | 9 | TreeNode::TreeNode(T& Data) 10 | { 11 | m_Data = Data; 12 | Init(); 13 | } 14 | 15 | TreeNode::~TreeNode(void) 16 | { 17 | Release(); 18 | } 19 | 20 | void TreeNode::Init() 21 | { 22 | m_lchild = NULL; 23 | m_rchild = NULL; 24 | m_parent = NULL; 25 | u.m_sign = 0; 26 | } 27 | 28 | void TreeNode::Release() 29 | { 30 | 31 | } 32 | 33 | int TreeNode::Height() 34 | { 35 | if ( this == NULL ) 36 | return -1; 37 | return u.m_height; 38 | } 39 | 40 | int TreeNode::FixHeight() 41 | { 42 | int nLeft = m_lchild->Height(); 43 | int nRight = m_rchild->Height(); 44 | 45 | if ( nLeft > nRight ) 46 | u.m_height = nLeft + 1; 47 | else 48 | u.m_height = nRight + 1; 49 | return u.m_height; 50 | } 51 | 52 | int GetNodeHeightDeep(TreeNode * Node) 53 | { 54 | if ( Node == NULL ) 55 | return -1; 56 | 57 | int nLeft = GetNodeHeightDeep(Node->m_lchild); 58 | int nRight = GetNodeHeightDeep(Node->m_rchild); 59 | 60 | if ( nLeft > nRight ) 61 | return nLeft + 1; 62 | return nRight + 1; 63 | } 64 | 65 | // bool IsLeftRed(TreeNode * Node) 66 | // { 67 | // if ( Node->m_lchild && 68 | // Node->m_lchild->u.m_color == NS_RED ) 69 | // return true; 70 | // return false; 71 | // } 72 | // 73 | // bool IsRightRed(TreeNode * Node) 74 | // { 75 | // if ( Node->m_rchild && 76 | // Node->m_rchild->u.m_color == NS_RED ) 77 | // return true; 78 | // return false; 79 | // } 80 | 81 | inline bool IsLeftRed(TreeNode * Node) 82 | { 83 | if ( Node->m_lchild && Node->m_lchild->u.m_color == NS_RED ) 84 | return true; 85 | return false; 86 | } 87 | 88 | inline bool IsRightRed(TreeNode * Node) 89 | { 90 | if ( Node->m_rchild && Node->m_rchild->u.m_color == NS_RED ) 91 | return true; 92 | return false; 93 | } 94 | 95 | inline void SwapColor(TreeNode * Node) 96 | { 97 | Node->u.m_color = NS_RED; 98 | Node->m_lchild->u.m_color = NS_BLACK; 99 | Node->m_rchild->u.m_color = NS_BLACK; 100 | } 101 | 102 | void Show(T& Data) 103 | { 104 | printf("%d ",Data); 105 | } 106 | 107 | void Show2(T& Data, int nSign) 108 | { 109 | printf("%d(%d) ",Data,nSign); 110 | } 111 | 112 | void ShowError(T& Data) 113 | { 114 | printf("\r\ncheck false %d\r\n", Data); 115 | } -------------------------------------------------------------------------------- /BalanceTree/BalanceTree.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件 29 | 30 | 31 | 头文件 32 | 33 | 34 | 头文件 35 | 36 | 37 | 头文件 38 | 39 | 40 | 头文件 41 | 42 | 43 | 头文件 44 | 45 | 46 | 头文件 47 | 48 | 49 | 头文件 50 | 51 | 52 | 头文件 53 | 54 | 55 | 头文件 56 | 57 | 58 | 59 | 60 | 源文件 61 | 62 | 63 | 源文件 64 | 65 | 66 | 源文件 67 | 68 | 69 | 源文件 70 | 71 | 72 | 源文件 73 | 74 | 75 | 源文件 76 | 77 | 78 | 源文件 79 | 80 | 81 | 源文件 82 | 83 | 84 | 源文件 85 | 86 | 87 | 源文件 88 | 89 | 90 | 源文件 91 | 92 | 93 | 源文件 94 | 95 | 96 | -------------------------------------------------------------------------------- /BalanceTree/Tree.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "Tree.h" 3 | 4 | Tree::Tree(void) 5 | { 6 | Init(); 7 | } 8 | 9 | Tree::~Tree(void) 10 | { 11 | Release(); 12 | } 13 | 14 | void Tree::Init() 15 | { 16 | m_root = NULL; 17 | } 18 | 19 | void Tree::Release() 20 | { 21 | Clear(); 22 | } 23 | 24 | bool Tree::Insert(T& Data) 25 | { 26 | return _Insert(&m_root, Data); 27 | } 28 | 29 | bool Tree::_Insert(TreeNode ** ppNode, T& Data) 30 | { 31 | bool bRet = false; 32 | TreeNode * pNode = *ppNode; 33 | if ( pNode == NULL ) 34 | { 35 | *ppNode = new TreeNode(Data); 36 | return *ppNode != NULL; 37 | } 38 | 39 | if ( Data < pNode->m_Data ) 40 | { 41 | bRet = _Insert(&pNode->m_lchild, Data); 42 | } 43 | else if ( Data > pNode->m_Data ) 44 | { 45 | bRet = _Insert(&pNode->m_rchild, Data); 46 | } 47 | else 48 | { 49 | bRet = false; 50 | } 51 | return bRet; 52 | } 53 | 54 | bool Tree::Delete(T& Data) 55 | { 56 | return _Delete(&m_root, Data); 57 | } 58 | 59 | bool Tree::_Delete(TreeNode ** ppNode, T& Data) 60 | { 61 | bool bRet = false; 62 | TreeNode * pNode = *ppNode; 63 | 64 | if ( Data < pNode->m_Data ) 65 | { 66 | bRet = _Delete(&pNode->m_lchild, Data); 67 | } 68 | else if( Data > pNode->m_Data ) 69 | { 70 | bRet = _Delete(&pNode->m_rchild, Data); 71 | } 72 | else 73 | { 74 | if ( pNode->m_rchild ) 75 | { 76 | TreeNode * tmp = FindMin(pNode->m_rchild); 77 | pNode->m_Data = tmp->m_Data; 78 | 79 | bRet = _Delete(&pNode->m_rchild, pNode->m_Data ); 80 | } 81 | else 82 | { 83 | TreeNode * tmp = pNode->m_lchild; 84 | 85 | delete pNode; 86 | 87 | *ppNode = tmp; 88 | } 89 | } 90 | return bRet; 91 | } 92 | 93 | int Tree::Size() 94 | { 95 | return _Size(m_root); 96 | } 97 | 98 | int Tree::_Size(TreeNode * Node) 99 | { 100 | if ( Node == NULL ) 101 | return 0; 102 | return _Size(Node->m_lchild) + _Size(Node->m_rchild) + 1; 103 | } 104 | 105 | void Tree::Clear() 106 | { 107 | _Clear(&m_root); 108 | } 109 | 110 | void Tree::_Clear(TreeNode ** ppNode) 111 | { 112 | if ( *ppNode == NULL ) 113 | return ; 114 | 115 | _Clear(&(*ppNode)->m_lchild); 116 | _Clear(&(*ppNode)->m_rchild); 117 | 118 | delete *ppNode; 119 | *ppNode = NULL; 120 | } 121 | 122 | void Tree::Traverse(PF_Show pfShow, int nType) 123 | { 124 | _Tranvers(m_root, pfShow, nType); 125 | } 126 | 127 | void Tree::Traverse(PF_Show2 pfShow2, int nType) 128 | { 129 | _Tranvers(m_root, pfShow2, nType); 130 | } 131 | 132 | TreeNode** Tree::GetParent(TreeNode * Node) 133 | { 134 | TreeNode * _parent = Node->m_parent; 135 | 136 | if ( _parent == NULL ) 137 | return &m_root; 138 | 139 | if ( Node == _parent->m_lchild ) 140 | return &_parent->m_lchild; 141 | return &_parent->m_rchild; 142 | } 143 | 144 | void Tree::_Tranvers(TreeNode * Node, PF_Show pfShow, int nType) 145 | { 146 | if ( Node == NULL ) 147 | return; 148 | 149 | switch(nType) 150 | { 151 | case NS_PREORDER: 152 | { 153 | if(pfShow != NULL) 154 | pfShow(Node->m_Data); 155 | _Tranvers(Node->m_lchild, pfShow, nType); 156 | _Tranvers(Node->m_rchild, pfShow, nType); 157 | break; 158 | } 159 | case NS_INORDER: 160 | { 161 | _Tranvers(Node->m_lchild, pfShow, nType); 162 | if(pfShow != NULL) 163 | pfShow(Node->m_Data); 164 | _Tranvers(Node->m_rchild, pfShow, nType); 165 | break; 166 | } 167 | case NS_POSTORDER: 168 | { 169 | _Tranvers(Node->m_lchild, pfShow, nType); 170 | _Tranvers(Node->m_rchild, pfShow, nType); 171 | if(pfShow != NULL) 172 | pfShow(Node->m_Data); 173 | break; 174 | } 175 | } 176 | } 177 | 178 | void Tree::_Tranvers(TreeNode * Node, PF_Show2 pfShow2, int nType) 179 | { 180 | if ( Node == NULL ) 181 | return; 182 | 183 | switch(nType) 184 | { 185 | case NS_PREORDER: 186 | { 187 | if(pfShow2 != NULL) 188 | pfShow2(Node->m_Data, Node->u.m_sign); 189 | _Tranvers(Node->m_lchild, pfShow2, nType); 190 | _Tranvers(Node->m_rchild, pfShow2, nType); 191 | break; 192 | } 193 | case NS_INORDER: 194 | { 195 | _Tranvers(Node->m_lchild, pfShow2, nType); 196 | if(pfShow2 != NULL) 197 | pfShow2(Node->m_Data, Node->u.m_sign); 198 | _Tranvers(Node->m_rchild, pfShow2, nType); 199 | break; 200 | } 201 | case NS_POSTORDER: 202 | { 203 | _Tranvers(Node->m_lchild, pfShow2, nType); 204 | _Tranvers(Node->m_rchild, pfShow2, nType); 205 | if(pfShow2 != NULL) 206 | pfShow2(Node->m_Data, Node->u.m_sign); 207 | break; 208 | } 209 | } 210 | } 211 | 212 | 213 | TreeNode * Tree::FindMin(TreeNode * Node) 214 | { 215 | if( Node == NULL ) 216 | return Node; 217 | while ( Node->m_lchild ) 218 | Node = Node->m_lchild; 219 | return Node; 220 | } 221 | 222 | TreeNode * Tree::FindMin2(TreeNode * Node) 223 | { 224 | if ( Node == NULL ) 225 | return Node; 226 | if ( Node->m_lchild == NULL ) 227 | return Node; 228 | return FindMin2(Node->m_lchild); 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /BalanceTree/BalanceTree.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 52 | 55 | 58 | 61 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 90 | 98 | 101 | 104 | 107 | 110 | 113 | 124 | 127 | 130 | 133 | 142 | 145 | 148 | 151 | 154 | 157 | 160 | 163 | 164 | 165 | 166 | 167 | 168 | 173 | 176 | 177 | 180 | 181 | 184 | 185 | 188 | 189 | 192 | 193 | 196 | 197 | 200 | 201 | 204 | 205 | 208 | 209 | 212 | 213 | 216 | 217 | 220 | 221 | 222 | 227 | 230 | 231 | 234 | 235 | 238 | 239 | 242 | 243 | 246 | 247 | 250 | 251 | 254 | 255 | 258 | 259 | 262 | 263 | 266 | 267 | 270 | 271 | 274 | 275 | 276 | 281 | 282 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /BalanceTree/BSTree2.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "BSTree2.h" 3 | 4 | 5 | BSTree2::BSTree2(void) 6 | { 7 | } 8 | 9 | 10 | BSTree2::~BSTree2(void) 11 | { 12 | } 13 | 14 | TreeNode* BSTree2::SingleRotateWithLeft(TreeNode * Node) 15 | { 16 | TreeNode * mid = Node->m_lchild; 17 | Node->m_lchild = mid->m_rchild; 18 | mid->m_rchild = Node; 19 | 20 | Node->FixHeight(); 21 | mid->u.m_height = Node->u.m_height + 1; 22 | 23 | return mid; 24 | } 25 | 26 | TreeNode* BSTree2::DoubleRotateWithLeft(TreeNode * Node) 27 | { 28 | TreeNode * mid = Node->m_lchild; 29 | TreeNode * tmp = mid->m_rchild; 30 | 31 | Node->m_lchild = tmp->m_rchild; 32 | mid->m_rchild = tmp->m_lchild; 33 | tmp->m_lchild = mid; 34 | tmp->m_rchild = Node; 35 | 36 | Node->FixHeight(); 37 | mid->u.m_height = Node->u.m_height; 38 | tmp->u.m_height = Node->u.m_height + 1; 39 | 40 | return tmp; 41 | } 42 | 43 | TreeNode* BSTree2::SingleRotateWithRight(TreeNode * Node) 44 | { 45 | TreeNode * mid = Node->m_rchild; 46 | 47 | Node->m_rchild = mid->m_lchild; 48 | mid->m_lchild = Node; 49 | 50 | Node->FixHeight(); 51 | mid->u.m_height = Node->u.m_height + 1; 52 | 53 | return mid; 54 | } 55 | 56 | TreeNode* BSTree2::DoubleRotateWithRight(TreeNode * Node) 57 | { 58 | 59 | TreeNode * mid = Node->m_rchild; 60 | TreeNode * tmp = mid->m_lchild; 61 | 62 | Node->m_rchild = tmp->m_lchild; 63 | mid->m_lchild = tmp->m_rchild; 64 | 65 | tmp->m_lchild = Node; 66 | tmp->m_rchild = mid; 67 | 68 | Node->FixHeight(); 69 | mid->u.m_height = Node->u.m_height; 70 | tmp->u.m_height = Node->u.m_height + 1; 71 | 72 | return tmp; 73 | } 74 | 75 | bool BSTree2::Insert(T& Data) 76 | { 77 | bool bSign = true; 78 | return _Insert(&m_root, Data, &bSign); 79 | } 80 | 81 | bool BSTree2::_Insert(TreeNode ** ppNode, T& Data, bool * bSign) 82 | { 83 | bool bRet = false; 84 | 85 | TreeNode * pNode = *ppNode; 86 | if ( pNode == NULL ) 87 | { 88 | *ppNode = new(std::nothrow) TreeNode(Data); 89 | if ( *ppNode == NULL ) 90 | { 91 | *bSign = false; 92 | return bRet; 93 | } 94 | return true; 95 | } 96 | 97 | if ( Data < pNode->m_Data ) 98 | { 99 | bRet = _Insert( &pNode->m_lchild, Data, bSign ); 100 | 101 | if ( *bSign ) 102 | { 103 | int height = (*ppNode)->u.m_height; 104 | if ( height == (*ppNode)->FixHeight() ) 105 | { 106 | *bSign = false; 107 | } 108 | else 109 | { 110 | if ( pNode->m_lchild->Height() - pNode->m_rchild->Height() == 2 ) 111 | { 112 | if ( Data < pNode->m_lchild->m_Data) 113 | *ppNode = SingleRotateWithLeft(pNode); 114 | else 115 | *ppNode = DoubleRotateWithLeft(pNode); 116 | 117 | *bSign = false; 118 | } 119 | } 120 | } 121 | } 122 | else if ( Data > pNode->m_Data ) 123 | { 124 | bRet = _Insert( &pNode->m_rchild, Data, bSign ); 125 | 126 | if ( *bSign ) 127 | { 128 | int height = (*ppNode)->u.m_height; 129 | if ( height == (*ppNode)->FixHeight() ) 130 | { 131 | *bSign = false; 132 | } 133 | else 134 | { 135 | if ( pNode->m_rchild->Height() - pNode->m_lchild->Height() == 2 ) 136 | { 137 | if ( Data > pNode->m_rchild->m_Data) 138 | *ppNode = SingleRotateWithRight(pNode); 139 | else 140 | *ppNode = DoubleRotateWithRight(pNode); 141 | 142 | *bSign = false; 143 | } 144 | } 145 | } 146 | } 147 | else 148 | { 149 | *bSign = false; 150 | return false; 151 | } 152 | 153 | return bRet; 154 | } 155 | 156 | bool BSTree2::Delete(T& Data) 157 | { 158 | bool bSign = false; 159 | return _Delete(&m_root, Data, &bSign); 160 | } 161 | 162 | bool BSTree2::_Delete(TreeNode ** ppNode, T& Data, bool * bSign) 163 | { 164 | bool bRet = false; 165 | TreeNode * pNode = *ppNode; 166 | if ( pNode == NULL ) 167 | { 168 | return bRet; 169 | } 170 | 171 | if ( Data < pNode->m_Data ) 172 | { 173 | bRet = _Delete(&pNode->m_lchild, Data, bSign); 174 | 175 | if ( *bSign ) 176 | { 177 | int height = (*ppNode)->u.m_height; 178 | 179 | if ( pNode->m_rchild->Height() - pNode->m_lchild->Height() == 2 ) 180 | { 181 | TreeNode * mid = pNode->m_rchild; 182 | if ( mid->m_rchild->Height() >= mid->m_lchild->Height() ) 183 | *ppNode = SingleRotateWithRight(pNode); 184 | else 185 | *ppNode = DoubleRotateWithRight(pNode); 186 | } 187 | 188 | if ( height == (*ppNode)->FixHeight()) 189 | *bSign = false; 190 | } 191 | } 192 | else if ( Data > pNode->m_Data ) 193 | { 194 | bRet = _Delete(&pNode->m_rchild, Data, bSign); 195 | 196 | if ( *bSign ) 197 | { 198 | int height = (*ppNode)->u.m_height; 199 | 200 | if ( pNode->m_lchild->Height() - pNode->m_rchild->Height() == 2 ) 201 | { 202 | TreeNode * mid = pNode->m_lchild; 203 | if ( mid->m_lchild->Height() >= mid->m_rchild->Height()) 204 | *ppNode = SingleRotateWithLeft(pNode); 205 | else 206 | *ppNode = DoubleRotateWithLeft(pNode); 207 | } 208 | 209 | if ( height == (*ppNode)->FixHeight()) 210 | *bSign = false; 211 | } 212 | } 213 | else 214 | { 215 | if ( pNode->m_rchild ) 216 | { 217 | TreeNode * Temp = FindMin(pNode->m_rchild); 218 | 219 | pNode->m_Data = Temp->m_Data; 220 | 221 | bRet = _Delete( &pNode->m_rchild, pNode->m_Data , bSign); 222 | 223 | if ( *bSign ) 224 | { 225 | int height = (*ppNode)->u.m_height; 226 | 227 | if ( pNode->m_lchild->Height() - pNode->m_rchild->Height() == 2 ) 228 | { 229 | TreeNode * mid = pNode->m_lchild; 230 | if ( mid->m_lchild->Height() >= mid->m_rchild->Height()) 231 | *ppNode = SingleRotateWithLeft(pNode); 232 | else 233 | *ppNode = DoubleRotateWithLeft(pNode); 234 | } 235 | 236 | if ( height == (*ppNode)->FixHeight()) 237 | *bSign = false; 238 | } 239 | } 240 | else 241 | { 242 | TreeNode * Temp = pNode->m_lchild; 243 | delete pNode; 244 | *ppNode = Temp; 245 | *bSign = true; 246 | bRet = true; 247 | } 248 | } 249 | 250 | return bRet; 251 | } 252 | 253 | bool BSTree2::Check() 254 | { 255 | return _Check(m_root , ShowError); 256 | } 257 | 258 | bool BSTree2::CheckNode(TreeNode * Node,PF_Show pfShow) 259 | { 260 | if ( Node == NULL ) 261 | return true; 262 | 263 | //int nLeft = GetHeight( Node->m_lchild ); 264 | //int nRight = GetHeight( Node->m_rchild ); 265 | 266 | int nLeft = Node->m_lchild->Height(); 267 | int nRight = Node->m_rchild->Height(); 268 | 269 | if ( nLeft > nRight ) 270 | { 271 | if ( nLeft - nRight > 1 ) 272 | { 273 | if( pfShow != NULL ) 274 | pfShow(Node->m_Data); 275 | return false; 276 | } 277 | } 278 | else 279 | { 280 | if ( nRight - nLeft > 1 ) 281 | { 282 | if( pfShow != NULL ) 283 | pfShow(Node->m_Data); 284 | return false; 285 | } 286 | } 287 | 288 | return true; 289 | } 290 | 291 | bool BSTree2::_Check(TreeNode * Node,PF_Show pfShow) 292 | { 293 | if ( Node == NULL ) 294 | return true; 295 | 296 | if ( CheckNode(Node, pfShow) == false ) 297 | return false; 298 | 299 | return _Check(Node->m_lchild, pfShow) && _Check(Node->m_rchild, pfShow); 300 | } 301 | -------------------------------------------------------------------------------- /BalanceTree/BSTree.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "BSTree.h" 3 | 4 | BSTree::BSTree(void) 5 | { 6 | } 7 | 8 | BSTree::~BSTree(void) 9 | { 10 | } 11 | 12 | TreeNode * BSTree::SingleRotateWithLeft(TreeNode * Node) 13 | { 14 | TreeNode * mid = Node->m_lchild; 15 | 16 | Node->m_lchild = mid->m_rchild; 17 | mid->m_rchild = Node; 18 | 19 | if( Node->m_lchild ) 20 | Node->m_lchild->m_parent = Node; 21 | 22 | mid->m_parent = Node->m_parent; 23 | Node->m_parent = mid; 24 | 25 | Node->FixHeight(); 26 | mid->u.m_height = Node->u.m_height + 1; 27 | 28 | return mid; 29 | } 30 | TreeNode * BSTree::DoubleRotateWithLeft(TreeNode * Node) 31 | { 32 | TreeNode * mid = Node->m_lchild; 33 | TreeNode * tmp = mid->m_rchild; 34 | 35 | Node->m_lchild = tmp->m_rchild; 36 | mid->m_rchild = tmp->m_lchild; 37 | 38 | if ( Node->m_lchild ) 39 | Node->m_lchild->m_parent = Node; 40 | if ( mid->m_rchild ) 41 | mid->m_rchild->m_parent = mid; 42 | 43 | tmp->m_lchild = mid; 44 | tmp->m_rchild = Node; 45 | 46 | tmp->m_parent = Node->m_parent; 47 | Node->m_parent = tmp; 48 | mid->m_parent = tmp; 49 | 50 | Node->FixHeight(); 51 | mid->u.m_height = Node->u.m_height; 52 | tmp->u.m_height = Node->u.m_height + 1; 53 | 54 | return tmp; 55 | } 56 | TreeNode * BSTree::SingleRotateWithRight(TreeNode * Node) 57 | { 58 | TreeNode * mid = Node->m_rchild; 59 | 60 | Node->m_rchild = mid->m_lchild; 61 | mid->m_lchild = Node; 62 | 63 | if ( Node->m_rchild ) 64 | Node->m_rchild->m_parent = Node; 65 | 66 | mid->m_parent = Node->m_parent; 67 | Node->m_parent = mid; 68 | 69 | Node->FixHeight(); 70 | mid->u.m_height = Node->u.m_height + 1; 71 | 72 | return mid; 73 | } 74 | TreeNode * BSTree::DoubleRotateWithRight(TreeNode * Node) 75 | { 76 | TreeNode * mid = Node->m_rchild; 77 | TreeNode * tmp = mid->m_lchild; 78 | 79 | Node->m_rchild = tmp->m_lchild; 80 | mid->m_lchild = tmp->m_rchild; 81 | 82 | if ( Node->m_rchild ) 83 | Node->m_rchild->m_parent = Node; 84 | if ( mid->m_lchild ) 85 | mid->m_lchild->m_parent = mid; 86 | 87 | tmp->m_lchild = Node; 88 | tmp->m_rchild = mid; 89 | 90 | tmp->m_parent = Node->m_parent; 91 | Node->m_parent = tmp; 92 | mid->m_parent = tmp; 93 | 94 | Node->FixHeight(); 95 | mid->u.m_height = Node->u.m_height; 96 | tmp->u.m_height = Node->u.m_height + 1; 97 | 98 | return tmp; 99 | } 100 | 101 | bool BSTree::Insert(T& Data) 102 | { 103 | TreeNode * _cur = m_root; 104 | TreeNode * _parent = NULL; 105 | 106 | while( _cur ) 107 | { 108 | if ( Data < _cur->m_Data ) 109 | { 110 | _parent = _cur; 111 | _cur = _cur->m_lchild; 112 | } 113 | else if ( Data > _cur->m_Data ) 114 | { 115 | _parent = _cur; 116 | _cur = _cur->m_rchild; 117 | } 118 | else 119 | { 120 | return false; 121 | } 122 | } 123 | 124 | _cur = new(std::nothrow) TreeNode(Data); 125 | if ( _cur == NULL ) 126 | return false; 127 | _cur->m_parent = _parent; 128 | 129 | if ( _parent == NULL ) 130 | { 131 | m_root = _cur; 132 | return true; 133 | } 134 | 135 | bool bLeft = false; 136 | if ( Data < _parent->m_Data ) 137 | { 138 | bLeft = true; 139 | _parent->m_lchild = _cur; 140 | } 141 | else 142 | { 143 | _parent->m_rchild = _cur; 144 | } 145 | 146 | do 147 | { 148 | int nHeight = _parent->u.m_height; 149 | if ( nHeight == _parent->FixHeight() ) 150 | break; 151 | 152 | if ( bLeft ) 153 | { 154 | bLeft = false; 155 | if ( _parent->m_lchild->Height() - _parent->m_rchild->Height() == 2 ) 156 | { 157 | TreeNode ** ppParent = GetParent(_parent); 158 | if ( _cur->m_lchild->Height() > _cur->m_rchild->Height() ) 159 | *ppParent = SingleRotateWithLeft(_parent); 160 | else 161 | *ppParent = DoubleRotateWithLeft(_parent); 162 | break; 163 | } 164 | } 165 | else 166 | { 167 | if ( _parent->m_rchild->Height() - _parent->m_lchild->Height() == 2 ) 168 | { 169 | TreeNode ** ppParent = GetParent(_parent); 170 | if ( _cur->m_rchild->Height() > _cur->m_lchild->Height() ) 171 | *ppParent = SingleRotateWithRight(_parent); 172 | else 173 | *ppParent = DoubleRotateWithRight(_parent); 174 | break; 175 | } 176 | } 177 | 178 | _cur = _parent; 179 | _parent = _cur->m_parent; 180 | 181 | if ( _parent == NULL ) 182 | break; 183 | 184 | if ( _cur == _parent->m_lchild ) 185 | bLeft = true; 186 | 187 | } while (true); 188 | 189 | return true; 190 | } 191 | 192 | bool BSTree::Delete(T& Data) 193 | { 194 | TreeNode * _cur = m_root; 195 | TreeNode * _parent = NULL; 196 | T _Data = Data; 197 | 198 | while ( _cur ) 199 | { 200 | if ( _Data < _cur->m_Data ) 201 | { 202 | _cur = _cur->m_lchild; 203 | } 204 | else if ( _Data > _cur->m_Data ) 205 | { 206 | _cur = _cur->m_rchild; 207 | } 208 | else 209 | { 210 | if ( _cur->m_rchild == NULL ) 211 | break; 212 | 213 | TreeNode * _min = FindMin(_cur->m_rchild); 214 | _cur->m_Data = _min->m_Data; 215 | _Data = _min->m_Data; 216 | _cur = _min; 217 | } 218 | } 219 | 220 | if ( _cur == NULL ) 221 | return false; 222 | 223 | _parent = _cur->m_parent; 224 | TreeNode * tmp = _cur->m_lchild; 225 | if ( tmp ) 226 | tmp->m_parent = _parent; 227 | delete _cur; 228 | 229 | if ( _parent == NULL ) 230 | { 231 | m_root = tmp; 232 | return true; 233 | } 234 | 235 | bool bLeft = false; 236 | if ( _cur == _parent->m_lchild ) 237 | { 238 | bLeft = true; 239 | _parent->m_lchild = tmp; 240 | } 241 | else 242 | { 243 | _parent->m_rchild = tmp; 244 | } 245 | 246 | do 247 | { 248 | int nHeight = _parent->Height(); 249 | 250 | if ( bLeft ) 251 | { 252 | bLeft = false; 253 | if ( _parent->m_rchild->Height() - _parent->m_lchild->Height() == 2 ) 254 | { 255 | TreeNode ** ppParent = GetParent(_parent); 256 | TreeNode * mid = _parent->m_rchild; 257 | if ( mid->m_rchild->Height() >= mid->m_lchild->Height() ) 258 | *ppParent = SingleRotateWithRight(_parent); 259 | else 260 | *ppParent = DoubleRotateWithRight(_parent); 261 | _parent = *ppParent; 262 | } 263 | } 264 | else 265 | { 266 | if ( _parent->m_lchild->Height() - _parent->m_rchild->Height() == 2) 267 | { 268 | TreeNode ** ppParent = GetParent(_parent); 269 | TreeNode * mid = _parent->m_lchild; 270 | if ( mid->m_lchild->Height() >= mid->m_rchild->Height() ) 271 | *ppParent = SingleRotateWithLeft(_parent); 272 | else 273 | *ppParent = DoubleRotateWithLeft(_parent); 274 | _parent = *ppParent; 275 | } 276 | } 277 | 278 | if ( nHeight == _parent->FixHeight() ) 279 | break; 280 | 281 | _cur = _parent; 282 | _parent = _cur->m_parent; 283 | 284 | if ( _parent == NULL ) 285 | break; 286 | 287 | if ( _cur == _parent->m_lchild ) 288 | bLeft = true; 289 | 290 | } while (true); 291 | 292 | return true; 293 | } 294 | 295 | bool BSTree::Check() 296 | { 297 | return _Check(m_root , ShowError); 298 | } 299 | 300 | bool BSTree::CheckNode(TreeNode * Node,PF_Show pfShow) 301 | { 302 | if ( Node == NULL ) 303 | return true; 304 | 305 | //int nLeft = GetHeight( Node->m_lchild ); 306 | //int nRight = GetHeight( Node->m_rchild ); 307 | 308 | int nLeft = Node->m_lchild->Height(); 309 | int nRight = Node->m_rchild->Height(); 310 | 311 | if ( nLeft > nRight ) 312 | { 313 | if ( nLeft - nRight > 1 ) 314 | { 315 | if( pfShow != NULL ) 316 | pfShow(Node->m_Data); 317 | return false; 318 | } 319 | } 320 | else 321 | { 322 | if ( nRight - nLeft > 1 ) 323 | { 324 | if( pfShow != NULL ) 325 | pfShow(Node->m_Data); 326 | return false; 327 | } 328 | } 329 | 330 | return true; 331 | } 332 | 333 | bool BSTree::_Check(TreeNode * Node,PF_Show pfShow) 334 | { 335 | if ( Node == NULL ) 336 | return true; 337 | 338 | if ( CheckNode(Node, pfShow) == false ) 339 | return false; 340 | 341 | return _Check(Node->m_lchild, pfShow) && _Check(Node->m_rchild, pfShow); 342 | } -------------------------------------------------------------------------------- /BalanceTree/AVLTree2.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AVLTree2.h" 3 | 4 | 5 | AVLTree2::AVLTree2(void) 6 | { 7 | } 8 | 9 | 10 | AVLTree2::~AVLTree2(void) 11 | { 12 | } 13 | 14 | TreeNode * AVLTree2::SingleRotateWithLeft(TreeNode* Node) 15 | { 16 | TreeNode * mid = Node->m_lchild; 17 | 18 | Node->m_lchild = mid->m_rchild; 19 | mid->m_rchild = Node; 20 | 21 | mid->u.m_bf = 0; 22 | Node->u.m_bf = 0; 23 | 24 | return mid; 25 | } 26 | 27 | TreeNode * AVLTree2::DoubleRotateWithLeft(TreeNode* Node) 28 | { 29 | TreeNode * mid = Node->m_lchild; 30 | TreeNode * tmp = mid->m_rchild; 31 | 32 | Node->m_lchild = tmp->m_rchild; 33 | mid->m_rchild = tmp->m_lchild; 34 | 35 | tmp->m_lchild = mid; 36 | tmp->m_rchild = Node; 37 | 38 | switch ( tmp->u.m_sign ) 39 | { 40 | case 0: 41 | { 42 | mid->u.m_bf = 0; 43 | Node->u.m_bf = 0; 44 | break; 45 | } 46 | case -1: 47 | { 48 | mid->u.m_bf = 0; 49 | Node->u.m_bf = 1; 50 | break; 51 | } 52 | case 1: 53 | { 54 | mid->u.m_bf = -1; 55 | Node->u.m_bf = 0; 56 | break; 57 | } 58 | } 59 | tmp->u.m_bf = 0; 60 | 61 | return tmp; 62 | } 63 | 64 | TreeNode * AVLTree2::SingleRotateWithRight(TreeNode* Node) 65 | { 66 | TreeNode * mid = Node->m_rchild; 67 | 68 | Node->m_rchild = mid->m_lchild; 69 | mid->m_lchild = Node; 70 | 71 | mid->u.m_bf = 0; 72 | Node->u.m_bf = 0; 73 | 74 | return mid; 75 | } 76 | 77 | TreeNode * AVLTree2::DoubleRotateWithRight(TreeNode* Node) 78 | { 79 | TreeNode * mid = Node->m_rchild; 80 | TreeNode * tmp = mid->m_lchild; 81 | 82 | Node->m_rchild = tmp->m_lchild; 83 | mid->m_lchild = tmp->m_rchild; 84 | 85 | tmp->m_lchild = Node; 86 | tmp->m_rchild = mid; 87 | 88 | switch ( tmp->u.m_bf ) 89 | { 90 | case 0: 91 | { 92 | mid->u.m_bf = 0; 93 | Node->u.m_bf = 0; 94 | break; 95 | } 96 | case -1: 97 | { 98 | Node->u.m_bf = 0; 99 | mid->u.m_bf = 1; 100 | break; 101 | } 102 | case 1: 103 | { 104 | Node->u.m_bf = -1; 105 | mid->u.m_bf = 0; 106 | break; 107 | } 108 | } 109 | tmp->u.m_bf = 0; 110 | 111 | return tmp; 112 | } 113 | 114 | bool AVLTree2::Insert(T& Data) 115 | { 116 | bool bSign = true; 117 | return _Insert(&m_root, Data ,&bSign); 118 | } 119 | 120 | bool AVLTree2::_Insert(TreeNode ** ppNode, T& Data, bool * bSign) 121 | { 122 | bool bRet = false; 123 | TreeNode * pNode = *ppNode; 124 | if ( pNode == NULL ) 125 | { 126 | *ppNode = new(std::nothrow) TreeNode(Data); 127 | if ( *ppNode == NULL ) 128 | { 129 | *bSign = false; 130 | return bRet; 131 | } 132 | return true; 133 | } 134 | 135 | if ( Data < pNode->m_Data ) 136 | { 137 | bRet = _Insert(&pNode->m_lchild, Data, bSign ); 138 | 139 | if ( *bSign ) 140 | { 141 | --pNode->u.m_bf; 142 | 143 | if ( pNode->u.m_bf == -2 ) 144 | { 145 | if ( pNode->m_lchild->u.m_sign == -1 ) 146 | *ppNode = SingleRotateWithLeft(pNode); 147 | else 148 | *ppNode = DoubleRotateWithLeft(pNode); 149 | *bSign = false; 150 | } 151 | else 152 | { 153 | if ( pNode->u.m_bf == 0 ) 154 | *bSign = false; 155 | } 156 | } 157 | } 158 | else if ( Data > pNode->m_Data ) 159 | { 160 | bRet = _Insert(&pNode->m_rchild, Data , bSign); 161 | 162 | if ( *bSign ) 163 | { 164 | ++pNode->u.m_bf; 165 | 166 | if ( pNode->u.m_bf == 2 ) 167 | { 168 | if ( pNode->m_rchild->u.m_sign == 1) 169 | *ppNode = SingleRotateWithRight(pNode); 170 | else 171 | *ppNode = DoubleRotateWithRight(pNode); 172 | *bSign = false; 173 | } 174 | else 175 | { 176 | if ( pNode->u.m_bf == 0 ) 177 | *bSign = false; 178 | } 179 | } 180 | } 181 | else 182 | { 183 | *bSign = false; 184 | return false; 185 | } 186 | return bRet; 187 | } 188 | 189 | TreeNode * AVLTree2::BalanceRotateWithLeft(TreeNode * Node) 190 | { 191 | TreeNode * mid = Node->m_lchild; 192 | 193 | Node->m_lchild = mid->m_rchild; // Node->m_lchild = mid->m_rchild; 194 | mid->m_rchild = Node; 195 | 196 | mid->u.m_bf = 1; 197 | Node->u.m_bf = -1; 198 | 199 | return mid; 200 | } 201 | 202 | TreeNode * AVLTree2::BalanceRotateWithRight(TreeNode * Node) 203 | { 204 | TreeNode * mid = Node->m_rchild; 205 | 206 | Node->m_rchild = mid->m_lchild; 207 | mid->m_lchild = Node; 208 | 209 | mid->u.m_bf = -1; 210 | Node->u.m_bf = 1; 211 | 212 | return mid; 213 | } 214 | 215 | bool AVLTree2::Delete(T& Data) 216 | { 217 | bool bSign = false; 218 | return _Delete(&m_root, Data, &bSign); 219 | } 220 | 221 | bool AVLTree2::_Delete(TreeNode ** ppNode, T& Data, bool * bSign) 222 | { 223 | bool bRet = false; 224 | TreeNode * pNode = *ppNode; 225 | if ( pNode == NULL ) 226 | return bRet; 227 | 228 | if ( Data < pNode->m_Data ) 229 | { 230 | bRet = _Delete(&pNode->m_lchild, Data, bSign ); 231 | 232 | if ( *bSign ) 233 | { 234 | ++pNode->u.m_bf; 235 | 236 | if ( pNode->u.m_bf == 2 ) 237 | { 238 | switch ( pNode->m_rchild->u.m_bf ) 239 | { 240 | case 0: 241 | { 242 | *ppNode = BalanceRotateWithRight(pNode); 243 | break; 244 | } 245 | case 1: 246 | { 247 | *ppNode = SingleRotateWithRight(pNode); 248 | break; 249 | } 250 | case -1: 251 | { 252 | *ppNode = DoubleRotateWithRight(pNode); 253 | break; 254 | } 255 | } 256 | } 257 | 258 | if ( (*ppNode)->u.m_bf != 0 ) 259 | *bSign = false; 260 | } 261 | } 262 | else if ( Data > pNode->m_Data ) 263 | { 264 | bRet = _Delete(&pNode->m_rchild, Data, bSign ); 265 | 266 | if ( *bSign ) 267 | { 268 | 269 | --pNode->u.m_bf; 270 | 271 | if ( pNode->u.m_bf == -2 ) 272 | { 273 | switch ( pNode->m_lchild->u.m_bf ) 274 | { 275 | case 0: 276 | { 277 | *ppNode = BalanceRotateWithLeft(pNode); 278 | break; 279 | } 280 | case -1: 281 | { 282 | *ppNode = SingleRotateWithLeft(pNode); 283 | break; 284 | } 285 | case 1: 286 | { 287 | *ppNode = DoubleRotateWithLeft(pNode); 288 | break; 289 | } 290 | } 291 | } 292 | 293 | if ( (*ppNode)->u.m_bf != 0 ) 294 | *bSign = false; 295 | } 296 | } 297 | else 298 | { 299 | if ( pNode->m_rchild ) 300 | { 301 | TreeNode * _min = FindMin(pNode->m_rchild); 302 | pNode->m_Data = _min->m_Data; 303 | 304 | bRet = _Delete( &pNode->m_rchild, pNode->m_Data, bSign ); 305 | 306 | if ( *bSign ) 307 | { 308 | 309 | --pNode->u.m_bf; 310 | 311 | if ( pNode->u.m_bf == -2 ) 312 | { 313 | switch ( pNode->m_lchild->u.m_bf ) 314 | { 315 | case 0: 316 | { 317 | *ppNode = BalanceRotateWithLeft(pNode); 318 | break; 319 | } 320 | case -1: 321 | { 322 | *ppNode = SingleRotateWithLeft(pNode); 323 | break; 324 | } 325 | case 1: 326 | { 327 | *ppNode = DoubleRotateWithLeft(pNode); 328 | break; 329 | } 330 | } 331 | } 332 | 333 | if ( (*ppNode)->u.m_bf != 0 ) 334 | *bSign = false; 335 | } 336 | 337 | } 338 | else 339 | { 340 | TreeNode * tmp = pNode->m_lchild; 341 | delete pNode; 342 | *ppNode = tmp; 343 | *bSign = true; 344 | bRet = true; 345 | } 346 | } 347 | 348 | return bRet; 349 | } 350 | 351 | 352 | 353 | bool AVLTree2::Check() 354 | { 355 | return _Check(m_root, ShowError); 356 | } 357 | 358 | bool AVLTree2::CheckNode(TreeNode * Node,PF_Show pfShow) 359 | { 360 | if ( Node == NULL ) 361 | return true; 362 | 363 | int nLeft = GetNodeHeightDeep( Node->m_lchild ); 364 | int nRight = GetNodeHeightDeep( Node->m_rchild ); 365 | 366 | if ( nLeft > nRight ) 367 | { 368 | if ( Node->u.m_bf != -1 ) 369 | { 370 | if( pfShow != NULL ) 371 | pfShow(Node->m_Data); 372 | return false; 373 | } 374 | if ( nLeft - nRight > 1 ) 375 | { 376 | if( pfShow != NULL ) 377 | pfShow(Node->m_Data); 378 | return false; 379 | } 380 | } 381 | else 382 | { 383 | if ( nLeft == nRight) 384 | { 385 | if ( Node->u.m_bf != 0 ) 386 | { 387 | if( pfShow != NULL ) 388 | pfShow(Node->m_Data); 389 | return false; 390 | } 391 | } 392 | else if( nLeft < nRight ) 393 | { 394 | if ( Node->u.m_bf != 1 ) 395 | { 396 | if( pfShow != NULL ) 397 | pfShow(Node->m_Data); 398 | return false; 399 | } 400 | } 401 | 402 | if ( nRight - nLeft > 1 ) 403 | { 404 | if( pfShow != NULL ) 405 | pfShow(Node->m_Data); 406 | return false; 407 | } 408 | } 409 | 410 | return true; 411 | } 412 | 413 | bool AVLTree2::_Check(TreeNode * Node,PF_Show pfShow) 414 | { 415 | if ( Node == NULL ) 416 | return true; 417 | 418 | if ( CheckNode(Node, pfShow) == false ) 419 | return false; 420 | 421 | return _Check(Node->m_lchild, pfShow) && _Check(Node->m_rchild, pfShow); 422 | } -------------------------------------------------------------------------------- /BalanceTree/BalanceTree.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {BD527E87-7B5F-4416-8E7F-E53E35D422C4} 23 | Win32Proj 24 | BalanceTree 25 | 26 | 27 | 28 | Application 29 | true 30 | v110 31 | Unicode 32 | 33 | 34 | Application 35 | true 36 | v110 37 | Unicode 38 | 39 | 40 | Application 41 | false 42 | v110 43 | true 44 | Unicode 45 | 46 | 47 | Application 48 | false 49 | v110 50 | true 51 | Unicode 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | 72 | 73 | true 74 | 75 | 76 | false 77 | 78 | 79 | false 80 | 81 | 82 | 83 | Use 84 | Level3 85 | Disabled 86 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 87 | true 88 | 89 | 90 | Console 91 | true 92 | 93 | 94 | 95 | 96 | Use 97 | Level3 98 | Disabled 99 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 100 | true 101 | 102 | 103 | Console 104 | true 105 | 106 | 107 | 108 | 109 | Level3 110 | Use 111 | MaxSpeed 112 | true 113 | true 114 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 115 | true 116 | 117 | 118 | Console 119 | true 120 | true 121 | true 122 | 123 | 124 | 125 | 126 | Level3 127 | Use 128 | MaxSpeed 129 | true 130 | true 131 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | Create 168 | Create 169 | Create 170 | Create 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /BalanceTree/AVLTree.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AVLTree.h" 3 | 4 | 5 | AVLTree::AVLTree(void) 6 | { 7 | } 8 | 9 | 10 | AVLTree::~AVLTree(void) 11 | { 12 | } 13 | 14 | TreeNode * AVLTree::SingleRotateWithLeft(TreeNode* Node) 15 | { 16 | TreeNode * mid = Node->m_lchild; 17 | 18 | Node->m_lchild = mid->m_rchild; 19 | mid->m_rchild = Node; 20 | 21 | if ( Node->m_lchild ) 22 | Node->m_lchild->m_parent = Node; 23 | 24 | mid->m_parent = Node->m_parent; 25 | Node->m_parent = mid; 26 | 27 | mid->u.m_bf = 0; 28 | Node->u.m_bf = 0; 29 | 30 | return mid; 31 | } 32 | 33 | TreeNode * AVLTree::DoubleRotateWithLeft(TreeNode* Node) 34 | { 35 | TreeNode * mid = Node->m_lchild; 36 | TreeNode * tmp = mid->m_rchild; 37 | 38 | Node->m_lchild = tmp->m_rchild; 39 | mid->m_rchild = tmp->m_lchild; 40 | 41 | if ( Node->m_lchild ) 42 | Node->m_lchild->m_parent = Node; 43 | if ( mid->m_rchild ) 44 | mid->m_rchild->m_parent = mid; 45 | 46 | tmp->m_lchild = mid; 47 | tmp->m_rchild = Node; 48 | 49 | tmp->m_parent = Node->m_parent; 50 | Node->m_parent = tmp; 51 | mid->m_parent = tmp; 52 | 53 | switch ( tmp->u.m_sign ) 54 | { 55 | case 0: 56 | { 57 | mid->u.m_bf = 0; 58 | Node->u.m_bf = 0; 59 | break; 60 | } 61 | case -1: 62 | { 63 | mid->u.m_bf = 0; 64 | Node->u.m_bf = 1; 65 | break; 66 | } 67 | case 1: 68 | { 69 | mid->u.m_bf = -1; 70 | Node->u.m_bf = 0; 71 | break; 72 | } 73 | } 74 | tmp->u.m_bf = 0; 75 | 76 | return tmp; 77 | } 78 | 79 | TreeNode * AVLTree::SingleRotateWithRight(TreeNode* Node) 80 | { 81 | TreeNode * mid = Node->m_rchild; 82 | 83 | Node->m_rchild = mid->m_lchild; 84 | mid->m_lchild = Node; 85 | 86 | if ( Node->m_rchild ) 87 | Node->m_rchild->m_parent = Node; 88 | 89 | mid->m_parent = Node->m_parent; 90 | Node->m_parent = mid; 91 | 92 | mid->u.m_bf = 0; 93 | Node->u.m_bf = 0; 94 | 95 | return mid; 96 | } 97 | 98 | TreeNode * AVLTree::DoubleRotateWithRight(TreeNode* Node) 99 | { 100 | TreeNode * mid = Node->m_rchild; 101 | TreeNode * tmp = mid->m_lchild; 102 | 103 | Node->m_rchild = tmp->m_lchild; 104 | mid->m_lchild = tmp->m_rchild; 105 | 106 | if ( Node->m_rchild ) 107 | Node->m_rchild->m_parent = Node; 108 | if ( mid->m_lchild ) 109 | mid->m_lchild->m_parent = mid; 110 | 111 | tmp->m_lchild = Node; 112 | tmp->m_rchild = mid; 113 | 114 | tmp->m_parent = Node->m_parent; 115 | Node->m_parent = tmp; 116 | mid->m_parent = tmp; 117 | 118 | switch ( tmp->u.m_bf ) 119 | { 120 | case 0: 121 | { 122 | mid->u.m_bf = 0; 123 | Node->u.m_bf = 0; 124 | break; 125 | } 126 | case -1: 127 | { 128 | Node->u.m_bf = 0; 129 | mid->u.m_bf = 1; 130 | break; 131 | } 132 | case 1: 133 | { 134 | Node->u.m_bf = -1; 135 | mid->u.m_bf = 0; 136 | break; 137 | } 138 | } 139 | tmp->u.m_bf = 0; 140 | 141 | return tmp; 142 | } 143 | 144 | bool AVLTree::Insert(T& Data) 145 | { 146 | TreeNode * _cur = m_root; 147 | TreeNode * _parent = NULL; 148 | 149 | while ( _cur ) 150 | { 151 | if ( Data < _cur->m_Data ) 152 | { 153 | _parent = _cur; 154 | _cur = _cur->m_lchild; 155 | } 156 | else if ( Data > _cur->m_Data ) 157 | { 158 | _parent = _cur; 159 | _cur = _cur->m_rchild; 160 | } 161 | else 162 | { 163 | return false; 164 | } 165 | } 166 | 167 | _cur = new(std::nothrow) TreeNode(Data); 168 | if ( _cur == NULL ) 169 | return false; 170 | _cur->m_parent = _parent; 171 | 172 | if ( _parent == NULL ) 173 | { 174 | m_root = _cur; 175 | return true; 176 | } 177 | 178 | bool bLeft = false; 179 | if ( Data < _parent->m_Data ) 180 | { 181 | bLeft = true; 182 | _parent->m_lchild = _cur; 183 | } 184 | else 185 | { 186 | _parent->m_rchild = _cur; 187 | } 188 | 189 | do 190 | { 191 | int nHeight = _parent->u.m_height; 192 | 193 | if ( bLeft ) 194 | { 195 | bLeft = false; 196 | 197 | --_parent->u.m_bf; 198 | if ( _parent->u.m_bf == 0 ) 199 | break; 200 | 201 | if ( _parent->u.m_bf == -2 ) 202 | { 203 | TreeNode ** ppParent = GetParent(_parent); 204 | if ( _cur->u.m_bf == -1 ) 205 | *ppParent = SingleRotateWithLeft(_parent); 206 | else 207 | *ppParent = DoubleRotateWithLeft(_parent); 208 | break; 209 | } 210 | } 211 | else 212 | { 213 | ++_parent->u.m_bf; 214 | if ( _parent->u.m_bf == 0 ) 215 | break; 216 | 217 | if ( _parent->u.m_bf == 2 ) 218 | { 219 | TreeNode ** ppParent = GetParent(_parent); 220 | if ( _cur->u.m_bf == 1 ) 221 | *ppParent = SingleRotateWithRight(_parent); 222 | else 223 | *ppParent = DoubleRotateWithRight(_parent); 224 | break; 225 | } 226 | } 227 | 228 | _cur = _parent; 229 | _parent = _cur->m_parent; 230 | 231 | if ( _parent == NULL ) 232 | break; 233 | 234 | if ( _cur == _parent->m_lchild ) 235 | bLeft = true; 236 | 237 | } while (true); 238 | 239 | return true; 240 | } 241 | 242 | TreeNode * AVLTree::BalanceRotateWithLeft(TreeNode * Node) 243 | { 244 | TreeNode * mid = Node->m_lchild; 245 | 246 | Node->m_lchild = mid->m_rchild; 247 | mid->m_rchild = Node; 248 | 249 | if ( Node->m_lchild ) 250 | Node->m_lchild->m_parent = Node; 251 | 252 | mid->m_parent = Node->m_parent; 253 | Node->m_parent = mid; 254 | 255 | mid->u.m_bf = 1; 256 | Node->u.m_bf = -1; 257 | 258 | return mid; 259 | } 260 | 261 | TreeNode * AVLTree::BalanceRotateWithRight(TreeNode * Node) 262 | { 263 | TreeNode * mid = Node->m_rchild; 264 | 265 | Node->m_rchild = mid->m_lchild; 266 | mid->m_lchild = Node; 267 | 268 | if ( Node->m_rchild ) 269 | Node->m_rchild->m_parent = Node; 270 | 271 | mid->m_parent = Node->m_parent; 272 | Node->m_parent = mid; 273 | 274 | mid->u.m_bf = -1; 275 | Node->u.m_bf = 1; 276 | 277 | return mid; 278 | } 279 | 280 | bool AVLTree::Delete(T& Data) 281 | { 282 | TreeNode * _cur = m_root; 283 | TreeNode * _parent = NULL; 284 | T _Data = Data; 285 | 286 | while ( _cur ) 287 | { 288 | if ( _Data < _cur->m_Data ) 289 | { 290 | _cur = _cur->m_lchild; 291 | } 292 | else if ( _Data > _cur->m_Data ) 293 | { 294 | _cur = _cur->m_rchild; 295 | } 296 | else 297 | { 298 | if ( _cur->m_rchild == NULL ) 299 | break; 300 | 301 | TreeNode * _min = FindMin(_cur->m_rchild); 302 | _cur->m_Data = _min->m_Data; 303 | _Data = _min->m_Data; 304 | _cur = _min; 305 | } 306 | } 307 | 308 | if ( _cur == NULL ) 309 | return false; 310 | 311 | _parent = _cur->m_parent; 312 | TreeNode * tmp = _cur->m_lchild; 313 | if ( tmp ) 314 | tmp->m_parent = _parent; 315 | 316 | delete _cur; 317 | 318 | if ( _parent == NULL ) 319 | { 320 | m_root = tmp; 321 | return true; 322 | } 323 | 324 | bool bLeft = false; 325 | if ( _cur == _parent->m_lchild ) 326 | { 327 | bLeft = true; 328 | _parent->m_lchild = tmp; 329 | } 330 | else 331 | { 332 | _parent->m_rchild = tmp; 333 | } 334 | 335 | do 336 | { 337 | if ( bLeft ) 338 | { 339 | bLeft = false; 340 | ++_parent->u.m_bf; 341 | 342 | if ( _parent->u.m_bf == 2 ) 343 | { 344 | TreeNode ** ppParent = GetParent(_parent); 345 | switch (_parent->m_rchild->u.m_bf) 346 | { 347 | case 0: 348 | { 349 | *ppParent = BalanceRotateWithRight(_parent); 350 | break; 351 | } 352 | case 1: 353 | { 354 | *ppParent = SingleRotateWithRight(_parent); 355 | break; 356 | } 357 | case -1: 358 | { 359 | *ppParent = DoubleRotateWithRight(_parent); 360 | break; 361 | } 362 | } 363 | _parent = *ppParent; 364 | } 365 | } 366 | else 367 | { 368 | --_parent->u.m_bf; 369 | 370 | if ( _parent->u.m_bf == -2 ) 371 | { 372 | TreeNode ** ppParent = GetParent(_parent); 373 | switch (_parent->m_lchild->u.m_bf) 374 | { 375 | case 0: 376 | { 377 | *ppParent = BalanceRotateWithLeft(_parent); 378 | break; 379 | } 380 | case -1: 381 | { 382 | *ppParent = SingleRotateWithLeft(_parent); 383 | break; 384 | } 385 | case 1: 386 | { 387 | *ppParent = DoubleRotateWithLeft(_parent); 388 | break; 389 | } 390 | } 391 | _parent = *ppParent; 392 | } 393 | } 394 | 395 | if ( _parent->u.m_bf != 0 ) 396 | break; 397 | 398 | _cur = _parent; 399 | _parent = _cur->m_parent; 400 | 401 | if ( _parent == NULL ) 402 | break; 403 | 404 | if ( _cur == _parent->m_lchild ) 405 | bLeft = true; 406 | 407 | } while (true); 408 | 409 | return true; 410 | } 411 | 412 | bool AVLTree::Check() 413 | { 414 | return _Check(m_root, ShowError); 415 | } 416 | 417 | bool AVLTree::CheckNode(TreeNode * Node,PF_Show pfShow) 418 | { 419 | if ( Node == NULL ) 420 | return true; 421 | 422 | int nLeft = GetNodeHeightDeep( Node->m_lchild ); 423 | int nRight = GetNodeHeightDeep( Node->m_rchild ); 424 | 425 | if ( nLeft > nRight ) 426 | { 427 | if ( Node->u.m_bf != -1 ) 428 | { 429 | if( pfShow != NULL ) 430 | pfShow(Node->m_Data); 431 | return false; 432 | } 433 | if ( nLeft - nRight > 1 ) 434 | { 435 | if( pfShow != NULL ) 436 | pfShow(Node->m_Data); 437 | return false; 438 | } 439 | } 440 | else 441 | { 442 | if ( nLeft == nRight) 443 | { 444 | if ( Node->u.m_bf != 0 ) 445 | { 446 | if( pfShow != NULL ) 447 | pfShow(Node->m_Data); 448 | return false; 449 | } 450 | } 451 | else if( nLeft < nRight ) 452 | { 453 | if ( Node->u.m_bf != 1 ) 454 | { 455 | if( pfShow != NULL ) 456 | pfShow(Node->m_Data); 457 | return false; 458 | } 459 | } 460 | 461 | if ( nRight - nLeft > 1 ) 462 | { 463 | if( pfShow != NULL ) 464 | pfShow(Node->m_Data); 465 | return false; 466 | } 467 | } 468 | 469 | return true; 470 | } 471 | 472 | bool AVLTree::_Check(TreeNode * Node,PF_Show pfShow) 473 | { 474 | if ( Node == NULL ) 475 | return true; 476 | 477 | if ( CheckNode(Node, pfShow) == false ) 478 | return false; 479 | 480 | return _Check(Node->m_lchild, pfShow) && _Check(Node->m_rchild, pfShow); 481 | } 482 | -------------------------------------------------------------------------------- /BalanceTree/RBTree.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "RBTree.h" 3 | 4 | 5 | RBTree::RBTree(void) 6 | { 7 | } 8 | 9 | 10 | RBTree::~RBTree(void) 11 | { 12 | } 13 | 14 | TreeNode* RBTree::SingleRotateWithLeft(TreeNode * Node) 15 | { 16 | TreeNode * mid = Node->m_lchild; 17 | 18 | if ( mid->m_rchild ) 19 | mid->m_rchild->m_parent = Node; 20 | 21 | Node->m_lchild = mid->m_rchild; 22 | mid->m_rchild = Node; 23 | 24 | mid->m_parent = Node->m_parent; 25 | Node->m_parent = mid; 26 | 27 | return mid; 28 | } 29 | 30 | TreeNode* RBTree::DoubleRotateWithLeft(TreeNode * Node) 31 | { 32 | TreeNode * mid = Node->m_lchild; 33 | TreeNode * tmp = mid->m_rchild; 34 | 35 | Node->m_lchild = tmp->m_rchild; 36 | mid->m_rchild = tmp->m_lchild; 37 | 38 | if (tmp->m_rchild) 39 | tmp->m_rchild->m_parent = Node; 40 | if (tmp->m_lchild) 41 | tmp->m_lchild->m_parent = mid; 42 | 43 | tmp->m_lchild = mid; 44 | tmp->m_rchild = Node; 45 | 46 | tmp->m_parent = Node->m_parent; 47 | mid->m_parent = tmp; 48 | Node->m_parent = tmp; 49 | 50 | return tmp; 51 | } 52 | 53 | TreeNode* RBTree::SingleRotateWithRight(TreeNode * Node) 54 | { 55 | TreeNode * mid = Node->m_rchild; 56 | 57 | if ( mid->m_lchild ) 58 | mid->m_lchild->m_parent = Node; 59 | 60 | Node->m_rchild = mid->m_lchild; 61 | mid->m_lchild = Node; 62 | 63 | mid->m_parent = Node->m_parent; 64 | Node->m_parent = mid; 65 | 66 | return mid; 67 | } 68 | 69 | TreeNode* RBTree::DoubleRotateWithRight(TreeNode * Node) 70 | { 71 | TreeNode * mid = Node->m_rchild; 72 | TreeNode * tmp = mid->m_lchild; 73 | 74 | Node->m_rchild = tmp->m_lchild; 75 | mid->m_lchild = tmp->m_rchild; 76 | 77 | if (tmp->m_lchild) 78 | tmp->m_lchild->m_parent = Node; 79 | if (tmp->m_rchild) 80 | tmp->m_rchild->m_parent = mid; 81 | 82 | tmp->m_rchild = mid; 83 | tmp->m_lchild = Node; 84 | 85 | tmp->m_parent = Node->m_parent; 86 | mid->m_parent = tmp; 87 | Node->m_parent = tmp; 88 | 89 | return tmp; 90 | } 91 | 92 | bool RBTree::Insert(T& Data) 93 | { 94 | TreeNode * _cur = m_root; 95 | TreeNode * _parent = NULL; 96 | 97 | while ( _cur ) 98 | { 99 | if ( Data < _cur->m_Data ) 100 | { 101 | _parent = _cur; 102 | _cur = _cur->m_lchild; 103 | } 104 | else if ( Data > _cur->m_Data ) 105 | { 106 | _parent = _cur; 107 | _cur = _cur->m_rchild; 108 | } 109 | else 110 | { 111 | return false; 112 | } 113 | } 114 | 115 | _cur = new(std::nothrow) TreeNode(Data); 116 | if (_cur == NULL ) 117 | return false; 118 | _cur->m_parent = _parent; 119 | 120 | if ( _parent == NULL ) 121 | { 122 | m_root = _cur; 123 | m_root->u.m_color = NS_BLACK; 124 | return true; 125 | } 126 | 127 | bool bLeft = false; 128 | if ( Data < _parent->m_Data ) 129 | { 130 | bLeft = true; 131 | _parent->m_lchild = _cur; 132 | } 133 | else 134 | { 135 | _parent->m_rchild = _cur; 136 | } 137 | 138 | while ( _parent->u.m_color == NS_RED ) 139 | { 140 | TreeNode * _grandpa = _parent->m_parent; 141 | if ( _grandpa == NULL ) 142 | { 143 | _parent->u.m_color = NS_BLACK; 144 | break; 145 | } 146 | 147 | if ( _parent == _grandpa->m_lchild ) 148 | { 149 | if ( IsRightRed(_grandpa)) 150 | { 151 | SwapColor(_grandpa); 152 | } 153 | else 154 | { 155 | TreeNode ** ppGrandpa = GetParent(_grandpa); 156 | if ( bLeft ) 157 | *ppGrandpa = SingleRotateWithLeft(_grandpa); 158 | else 159 | *ppGrandpa = DoubleRotateWithLeft(_grandpa); 160 | 161 | (*ppGrandpa)->u.m_color = NS_BLACK; 162 | (*ppGrandpa)->m_rchild->u.m_color = NS_RED; 163 | break; 164 | } 165 | } 166 | else 167 | { 168 | if ( IsLeftRed(_grandpa)) 169 | { 170 | SwapColor(_grandpa); 171 | } 172 | else 173 | { 174 | TreeNode ** ppGrandpa = GetParent(_grandpa); 175 | if ( bLeft == false ) 176 | *ppGrandpa = SingleRotateWithRight(_grandpa); 177 | else 178 | *ppGrandpa = DoubleRotateWithRight(_grandpa); 179 | 180 | (*ppGrandpa)->u.m_color = NS_BLACK; 181 | (*ppGrandpa)->m_lchild->u.m_color = NS_RED; 182 | break; 183 | } 184 | } 185 | 186 | _cur = _grandpa; 187 | _parent = _cur->m_parent; 188 | 189 | if ( _parent == NULL ) 190 | { 191 | _cur->u.m_color = NS_BLACK; 192 | break; 193 | } 194 | 195 | bLeft = false; 196 | if ( _cur == _parent->m_lchild ) 197 | bLeft = true; 198 | } 199 | 200 | return true; 201 | } 202 | 203 | bool RBTree::Delete(T& Data) 204 | { 205 | TreeNode * _cur = m_root; 206 | TreeNode * _parent = NULL; 207 | T _Data = Data; 208 | TreeNode * _min = NULL; 209 | 210 | while ( _cur ) 211 | { 212 | if ( _Data < _cur->m_Data ) 213 | { 214 | _cur = _cur->m_lchild; 215 | } 216 | else if ( _Data > _cur->m_Data ) 217 | { 218 | _cur = _cur->m_rchild; 219 | } 220 | else 221 | { 222 | if ( _cur->m_rchild == NULL ) 223 | break; 224 | 225 | _min = FindMin(_cur->m_rchild); 226 | _cur->m_Data = _min->m_Data; 227 | _Data = _min->m_Data; 228 | _cur = _min; 229 | } 230 | } 231 | 232 | if ( _cur == NULL ) 233 | return false; 234 | _parent = _cur->m_parent; 235 | TreeNode * tmp = _cur->m_lchild; 236 | if ( tmp ) 237 | tmp->m_parent = _parent; 238 | 239 | bool bLeft = false; 240 | if ( _parent == NULL ) 241 | { 242 | delete _cur; 243 | m_root = tmp; 244 | if ( tmp ) 245 | tmp->u.m_color = NS_BLACK; 246 | return true; 247 | } 248 | else 249 | { 250 | if ( _cur->u.m_color == NS_RED || 251 | IsLeftRed(_cur) 252 | ) 253 | { 254 | 255 | if ( _cur == _parent->m_lchild ) 256 | { 257 | _parent->m_lchild = tmp; 258 | } 259 | else 260 | { 261 | _parent->m_rchild = tmp; 262 | } 263 | 264 | delete _cur; 265 | 266 | if ( tmp && 267 | tmp->u.m_color == NS_RED ) 268 | { 269 | tmp->u.m_color = NS_BLACK; 270 | } 271 | 272 | return true; 273 | } 274 | } 275 | 276 | if ( _cur == _parent->m_lchild ) 277 | bLeft = true; 278 | _min = _cur; 279 | 280 | bool bSign = false; 281 | do 282 | { 283 | if ( _cur->u.m_color == NS_RED ) 284 | { 285 | _cur->u.m_color = NS_BLACK; 286 | break; 287 | } 288 | else 289 | { 290 | if ( bLeft ) 291 | { 292 | TreeNode ** ppParent = GetParent(_parent); 293 | TreeNode * mid = _parent->m_rchild; 294 | if ( mid->u.m_color == NS_BLACK ) 295 | { 296 | if ( IsRightRed(mid)) 297 | { 298 | *ppParent = SingleRotateWithRight(_parent); 299 | 300 | (*ppParent)->u.m_color = (*ppParent)->m_lchild->u.m_color; 301 | (*ppParent)->m_lchild->u.m_color = NS_BLACK; 302 | (*ppParent)->m_rchild->u.m_color = NS_BLACK; 303 | 304 | bSign = true; 305 | } 306 | else if ( IsLeftRed(mid)) 307 | { 308 | *ppParent = DoubleRotateWithRight(_parent); 309 | 310 | (*ppParent)->u.m_color = (*ppParent)->m_lchild->u.m_color; 311 | (*ppParent)->m_lchild->u.m_color = NS_BLACK; 312 | 313 | bSign = true; 314 | } 315 | else 316 | { 317 | mid->u.m_color = NS_RED; 318 | } 319 | } 320 | else 321 | { 322 | *ppParent = SingleRotateWithRight(_parent); 323 | 324 | (*ppParent)->u.m_color = (*ppParent)->m_lchild->u.m_color; 325 | (*ppParent)->m_lchild->u.m_color = NS_RED; 326 | 327 | continue; 328 | } 329 | } 330 | else 331 | { 332 | TreeNode ** ppParent = GetParent(_parent); 333 | TreeNode * mid = _parent->m_lchild; 334 | if ( mid->u.m_color == NS_BLACK ) 335 | { 336 | if ( IsLeftRed(mid)) 337 | { 338 | *ppParent = SingleRotateWithLeft(_parent); 339 | 340 | (*ppParent)->u.m_color = (*ppParent)->m_rchild->u.m_color; 341 | (*ppParent)->m_lchild->u.m_color = NS_BLACK; 342 | (*ppParent)->m_rchild->u.m_color = NS_BLACK; 343 | 344 | bSign = true; 345 | } 346 | else if ( IsRightRed(mid)) 347 | { 348 | *ppParent = DoubleRotateWithLeft(_parent); 349 | 350 | (*ppParent)->u.m_color = (*ppParent)->m_rchild->u.m_color; 351 | (*ppParent)->m_rchild->u.m_color = NS_BLACK; 352 | 353 | bSign = true; 354 | } 355 | else 356 | { 357 | mid->u.m_color = NS_RED; 358 | } 359 | } 360 | else 361 | { 362 | *ppParent = SingleRotateWithLeft(_parent); 363 | 364 | (*ppParent)->u.m_color = (*ppParent)->m_rchild->u.m_color; 365 | (*ppParent)->m_rchild->u.m_color = NS_RED; 366 | 367 | continue; 368 | } 369 | } 370 | 371 | // del 372 | if ( _cur == _min ) 373 | { 374 | delete _cur; 375 | 376 | if ( bLeft ) 377 | _parent->m_lchild = tmp; 378 | else 379 | _parent->m_rchild = tmp; 380 | 381 | //_cur = tmp; 382 | } 383 | } 384 | 385 | if ( bSign ) 386 | break; 387 | 388 | _cur = _parent; 389 | _parent = _cur->m_parent; 390 | 391 | if ( _parent == NULL ) 392 | { 393 | _cur->u.m_color = NS_BLACK; 394 | break; 395 | } 396 | 397 | bLeft = false; 398 | if ( _cur == _parent->m_lchild ) 399 | bLeft = true; 400 | 401 | } while (true); 402 | 403 | return true; 404 | } 405 | 406 | bool RBTree::Check() 407 | { 408 | if ( m_root && 409 | m_root->u.m_color != NS_BLACK ) 410 | return false; 411 | return _Check( m_root ); 412 | } 413 | 414 | int RBTree::GetBlackNodeLeft(TreeNode * Node) 415 | { 416 | if ( Node == NULL ) 417 | return -1; 418 | int nBlock = Node->u.m_color == NS_BLACK; 419 | return GetBlackNodeLeft(Node->m_lchild) + nBlock; 420 | } 421 | 422 | int RBTree::GetBlackNodeRight(TreeNode * Node) 423 | { 424 | if ( Node == NULL ) 425 | return -1; 426 | int nBlock = Node->u.m_color == NS_BLACK; 427 | return GetBlackNodeRight(Node->m_rchild) + nBlock; 428 | } 429 | 430 | bool RBTree::_Check(TreeNode * Node) 431 | { 432 | if ( Node == NULL ) 433 | return true; 434 | 435 | int nLeft = GetBlackNodeLeft(Node->m_lchild); 436 | int nRight = GetBlackNodeRight(Node->m_rchild); 437 | 438 | // if ( Node == m_root ) 439 | // { 440 | // printf("Root left Black Node %d right Black Node %d \r\n",nLeft + 1, nRight + 1); 441 | // } 442 | 443 | if( nLeft != nRight) 444 | { 445 | printf("Data %d left Black Node %d != right Black Node %d \r\n", Node->m_Data, nLeft + 1, nRight + 1); 446 | return false; 447 | } 448 | 449 | if ( Node->u.m_color == NS_RED ) 450 | { 451 | if ( Node->m_lchild && Node->m_lchild->u.m_color == NS_RED ) 452 | { 453 | printf("double L red %d-->%d \r\n", Node->m_Data, Node->m_lchild->m_Data ); 454 | return false; 455 | } 456 | 457 | if ( Node->m_rchild && Node->m_rchild->u.m_color == NS_RED ) 458 | { 459 | printf("double R red %d-->%d \r\n", Node->m_Data, Node->m_rchild->m_Data ); 460 | return false; 461 | } 462 | } 463 | 464 | if ( _Check(Node->m_lchild) == false ) 465 | return false; 466 | 467 | if ( _Check(Node->m_rchild) == false ) 468 | return false; 469 | 470 | return true; 471 | } 472 | -------------------------------------------------------------------------------- /BalanceTree/RBTree3.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "RBTree3.h" 3 | 4 | 5 | RBTree3::RBTree3(void) 6 | { 7 | } 8 | 9 | 10 | RBTree3::~RBTree3(void) 11 | { 12 | } 13 | 14 | TreeNode* RBTree3::SingleRotateWithLeft(TreeNode * Node) 15 | { 16 | TreeNode * mid = Node->m_lchild; 17 | Node->m_lchild = mid->m_rchild; 18 | mid->m_rchild = Node; 19 | 20 | return mid; 21 | } 22 | 23 | TreeNode* RBTree3::DoubleRotateWithLeft(TreeNode * Node) 24 | { 25 | TreeNode * mid = Node->m_lchild; 26 | TreeNode * tmp = mid->m_rchild; 27 | 28 | Node->m_lchild = tmp->m_rchild; 29 | mid->m_rchild = tmp->m_lchild; 30 | tmp->m_lchild = mid; 31 | tmp->m_rchild = Node; 32 | 33 | return tmp; 34 | } 35 | 36 | TreeNode* RBTree3::SingleRotateWithRight(TreeNode * Node) 37 | { 38 | TreeNode * mid = Node->m_rchild; 39 | 40 | Node->m_rchild = mid->m_lchild; 41 | mid->m_lchild = Node; 42 | 43 | return mid; 44 | } 45 | 46 | TreeNode* RBTree3::DoubleRotateWithRight(TreeNode * Node) 47 | { 48 | 49 | TreeNode * mid = Node->m_rchild; 50 | TreeNode * tmp = mid->m_lchild; 51 | 52 | Node->m_rchild = tmp->m_lchild; 53 | mid->m_lchild = tmp->m_rchild; 54 | 55 | tmp->m_lchild = Node; 56 | tmp->m_rchild = mid; 57 | 58 | return tmp; 59 | } 60 | 61 | bool RBTree3::Insert(T& Data) 62 | { 63 | bool bSign = true; 64 | bool bRet = _Insert(&m_root, Data, &bSign); 65 | if ( m_root ) 66 | m_root->u.m_color = NS_BLACK; 67 | return bRet; 68 | } 69 | 70 | inline bool IsLeftRed(TreeNode * Node) 71 | { 72 | if ( Node->m_lchild && Node->m_lchild->u.m_color == NS_RED ) 73 | return true; 74 | return false; 75 | } 76 | 77 | inline bool IsRightRed(TreeNode * Node) 78 | { 79 | if ( Node->m_rchild && Node->m_rchild->u.m_color == NS_RED ) 80 | return true; 81 | return false; 82 | } 83 | 84 | inline void SwapColor(TreeNode * Node) 85 | { 86 | Node->u.m_color = NS_RED; 87 | Node->m_lchild->u.m_color = NS_BLACK; 88 | Node->m_rchild->u.m_color = NS_BLACK; 89 | } 90 | 91 | bool RBTree3::_Insert(TreeNode ** ppNode, T& Data, bool * bSign) 92 | { 93 | bool bRet = false; 94 | TreeNode * pNode = *ppNode; 95 | if ( pNode == NULL ) 96 | { 97 | *ppNode = new(std::nothrow) TreeNode(Data); 98 | if ( *ppNode == NULL ) 99 | { 100 | *bSign = false; 101 | return false; 102 | } 103 | return true; 104 | } 105 | 106 | if ( Data < pNode->m_Data ) 107 | { 108 | bRet = _Insert(&pNode->m_lchild, Data, bSign ); 109 | if(*bSign) 110 | { 111 | TreeNode * mid = pNode->m_lchild; 112 | if ( mid->u.m_color == NS_RED ) 113 | { 114 | if ( IsLeftRed(mid) ) 115 | { 116 | if ( IsRightRed(pNode)) 117 | { 118 | SwapColor(pNode); 119 | } 120 | else 121 | { 122 | *ppNode = SingleRotateWithLeft(pNode); 123 | 124 | (*ppNode)->u.m_color = NS_BLACK; 125 | (*ppNode)->m_rchild->u.m_color = NS_RED; 126 | 127 | *bSign = false; 128 | } 129 | } 130 | else if ( IsRightRed(mid) ) 131 | { 132 | if ( IsRightRed(pNode)) 133 | { 134 | SwapColor(pNode); 135 | } 136 | else 137 | { 138 | *ppNode = DoubleRotateWithLeft(pNode); 139 | 140 | (*ppNode)->u.m_color = NS_BLACK; 141 | (*ppNode)->m_rchild->u.m_color = NS_RED; 142 | 143 | *bSign = false; 144 | } 145 | } 146 | } 147 | } 148 | } 149 | else if ( Data > pNode->m_Data ) 150 | { 151 | bRet = _Insert(&pNode->m_rchild, Data, bSign ); 152 | if(*bSign) 153 | { 154 | TreeNode * mid = pNode->m_rchild; 155 | if ( mid->u.m_color == NS_RED ) 156 | { 157 | if ( IsRightRed(mid) ) 158 | { 159 | if ( IsLeftRed(pNode)) 160 | { 161 | SwapColor(pNode); 162 | } 163 | else 164 | { 165 | *ppNode = SingleRotateWithRight(pNode); 166 | 167 | (*ppNode)->u.m_color = NS_BLACK; 168 | (*ppNode)->m_lchild->u.m_color = NS_RED; 169 | 170 | *bSign = false; 171 | } 172 | } 173 | else if ( IsLeftRed(mid) ) 174 | { 175 | if ( IsLeftRed(pNode)) 176 | { 177 | SwapColor(pNode); 178 | } 179 | else 180 | { 181 | *ppNode = DoubleRotateWithRight(pNode); 182 | 183 | (*ppNode)->u.m_color = NS_BLACK; 184 | (*ppNode)->m_lchild->u.m_color = NS_RED; 185 | 186 | *bSign = false; 187 | } 188 | } 189 | } 190 | } 191 | } 192 | else 193 | { 194 | *bSign = false; 195 | return false; 196 | } 197 | 198 | return bRet; 199 | } 200 | 201 | bool RBTree3::Delete(T& Data) 202 | { 203 | bool bSign = false; 204 | bool bRet = _Delete(&m_root, Data, &bSign); 205 | if ( m_root ) 206 | m_root->u.m_color = NS_BLACK; 207 | return bRet; 208 | } 209 | 210 | TreeNode * RBTree3::FixBlackTreeWithLeft(TreeNode * Node) 211 | { 212 | TreeNode * mid = Node->m_lchild; 213 | if ( IsLeftRed(mid) && IsRightRed(mid) ) 214 | { 215 | Node = SingleRotateWithLeft(Node); 216 | SwapColor(Node); 217 | } 218 | else if ( IsRightRed(mid) ) 219 | { 220 | Node = DoubleRotateWithLeft(Node); 221 | 222 | Node->m_rchild->u.m_color = NS_BLACK; 223 | } 224 | else 225 | { 226 | Node = SingleRotateWithLeft(Node); 227 | } 228 | 229 | return Node; 230 | } 231 | 232 | TreeNode * RBTree3::FixBlackTreeWithRight(TreeNode * Node) 233 | { 234 | TreeNode * mid = Node->m_rchild; 235 | if ( IsLeftRed(mid) && IsRightRed(mid) ) 236 | { 237 | Node = SingleRotateWithRight(Node); 238 | SwapColor(Node); 239 | } 240 | else if ( IsLeftRed(mid) ) 241 | { 242 | Node = DoubleRotateWithRight(Node); 243 | 244 | Node->m_lchild->u.m_color = NS_BLACK; 245 | } 246 | else 247 | { 248 | Node = SingleRotateWithRight(Node); 249 | } 250 | 251 | return Node; 252 | } 253 | 254 | 255 | bool RBTree3::_Delete(TreeNode ** ppNode, T& Data, bool * bSign) 256 | { 257 | bool bRet = false; 258 | TreeNode * pNode = *ppNode; 259 | 260 | if ( pNode == NULL ) 261 | return false; 262 | 263 | if ( Data < pNode->m_Data ) 264 | { 265 | bRet = _Delete(&pNode->m_lchild, Data, bSign); 266 | if ( *bSign ) 267 | { 268 | if ( pNode->u.m_color == NS_BLACK ) 269 | { 270 | TreeNode * mid = pNode->m_rchild; 271 | if ( mid->u.m_color == NS_BLACK ) 272 | { 273 | if ( IsRightRed(mid) ) 274 | { 275 | *ppNode = SingleRotateWithRight(pNode); 276 | 277 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 278 | *bSign = false; 279 | } 280 | else if ( IsLeftRed(mid)) 281 | { 282 | *ppNode = DoubleRotateWithRight(pNode); 283 | 284 | (*ppNode)->u.m_color = NS_BLACK; 285 | *bSign = false; 286 | } 287 | else 288 | { 289 | mid->u.m_color = NS_RED; // goon 290 | } 291 | } 292 | else 293 | { 294 | // ºÚºìºÚºÚ 295 | *ppNode = SingleRotateWithRight(pNode); 296 | 297 | (*ppNode)->u.m_color = NS_BLACK; 298 | (*ppNode)->m_lchild->u.m_color = NS_RED; 299 | 300 | // ¶þ´Îµ÷Õû 301 | (*ppNode)->m_lchild = FixBlackTreeWithRight((*ppNode)->m_lchild); 302 | *bSign = false; 303 | } 304 | } 305 | else 306 | { 307 | // ºìºÚ XX 308 | TreeNode * mid = pNode->m_rchild; 309 | if ( IsLeftRed(mid) ) 310 | { 311 | *ppNode = DoubleRotateWithRight(pNode); 312 | 313 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 314 | *bSign = false; 315 | } 316 | else 317 | { 318 | *ppNode = SingleRotateWithRight(pNode); 319 | 320 | *bSign = false; 321 | } 322 | } 323 | } 324 | } 325 | else if ( Data > pNode->m_Data ) 326 | { 327 | bRet = _Delete(&pNode->m_rchild, Data, bSign); 328 | if ( *bSign ) 329 | { 330 | if ( pNode->u.m_color == NS_BLACK ) 331 | { 332 | TreeNode * mid = pNode->m_lchild; 333 | if ( mid->u.m_color == NS_BLACK ) 334 | { 335 | if ( IsLeftRed(mid) ) 336 | { 337 | *ppNode = SingleRotateWithLeft(pNode); 338 | 339 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 340 | *bSign = false; 341 | } 342 | else if ( IsRightRed(mid)) 343 | { 344 | *ppNode = DoubleRotateWithLeft(pNode); 345 | 346 | (*ppNode)->u.m_color = NS_BLACK; 347 | *bSign = false; 348 | } 349 | else 350 | { 351 | mid->u.m_color = NS_RED; // goon 352 | } 353 | } 354 | else 355 | { 356 | // ºÚºìºÚºÚ 357 | *ppNode = SingleRotateWithLeft(pNode); 358 | 359 | (*ppNode)->u.m_color = NS_BLACK; 360 | (*ppNode)->m_rchild->u.m_color = NS_RED; 361 | 362 | // ¶þ´Îµ÷Õû 363 | (*ppNode)->m_rchild = FixBlackTreeWithLeft((*ppNode)->m_rchild); 364 | *bSign = false; 365 | } 366 | } 367 | else 368 | { 369 | // ºìºÚ XX 370 | TreeNode * mid = pNode->m_lchild; 371 | if ( IsRightRed(mid) ) 372 | { 373 | *ppNode = DoubleRotateWithLeft(pNode); 374 | 375 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 376 | *bSign = false; 377 | } 378 | else 379 | { 380 | *ppNode = SingleRotateWithLeft(pNode); 381 | 382 | *bSign = false; 383 | } 384 | } 385 | } 386 | } 387 | else 388 | { 389 | if ( pNode->m_rchild ) 390 | { 391 | TreeNode * tmp = FindMin( pNode->m_rchild ); 392 | pNode->m_Data = tmp->m_Data; 393 | 394 | bRet = _Delete(&pNode->m_rchild, pNode->m_Data, bSign); 395 | if ( *bSign ) 396 | { 397 | if ( pNode->u.m_color == NS_BLACK ) 398 | { 399 | TreeNode * mid = pNode->m_lchild; 400 | if ( mid->u.m_color == NS_BLACK ) 401 | { 402 | if ( IsLeftRed(mid) ) 403 | { 404 | *ppNode = SingleRotateWithLeft(pNode); 405 | 406 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 407 | *bSign = false; 408 | } 409 | else if ( IsRightRed(mid)) 410 | { 411 | *ppNode = DoubleRotateWithLeft(pNode); 412 | 413 | (*ppNode)->u.m_color = NS_BLACK; 414 | *bSign = false; 415 | } 416 | else 417 | { 418 | mid->u.m_color = NS_RED; // goon 419 | } 420 | } 421 | else 422 | { 423 | // ºÚºìºÚºÚ 424 | *ppNode = SingleRotateWithLeft(pNode); 425 | 426 | (*ppNode)->u.m_color = NS_BLACK; 427 | (*ppNode)->m_rchild->u.m_color = NS_RED; 428 | 429 | // ¶þ´Îµ÷Õû 430 | (*ppNode)->m_rchild = FixBlackTreeWithLeft((*ppNode)->m_rchild); 431 | *bSign = false; 432 | } 433 | } 434 | else 435 | { 436 | // ºìºÚ XX 437 | TreeNode * mid = pNode->m_lchild; 438 | if ( IsRightRed(mid) ) 439 | { 440 | *ppNode = DoubleRotateWithLeft(pNode); 441 | 442 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 443 | *bSign = false; 444 | } 445 | else 446 | { 447 | *ppNode = SingleRotateWithLeft(pNode); 448 | 449 | *bSign = false; 450 | } 451 | } 452 | } 453 | } 454 | else 455 | { 456 | TreeNode * tmp = pNode->m_lchild; 457 | 458 | if ( pNode->u.m_color == NS_BLACK ) 459 | *bSign = true; 460 | 461 | delete pNode; 462 | *ppNode = tmp; 463 | 464 | if ( tmp && tmp->u.m_color == NS_RED ) 465 | { 466 | tmp->u.m_color = NS_BLACK; 467 | *bSign = false; 468 | } 469 | 470 | bRet = true; 471 | } 472 | } 473 | 474 | return bRet; 475 | } 476 | 477 | bool RBTree3::Check() 478 | { 479 | if ( m_root && 480 | m_root->u.m_color != NS_BLACK ) 481 | return false; 482 | return _Check( m_root ); 483 | } 484 | 485 | int RBTree3::GetBlackNodeLeft(TreeNode * Node) 486 | { 487 | if ( Node == NULL ) 488 | return -1; 489 | int nBlock = Node->u.m_color == NS_BLACK; 490 | return GetBlackNodeLeft(Node->m_lchild) + nBlock; 491 | } 492 | 493 | int RBTree3::GetBlackNodeRight(TreeNode * Node) 494 | { 495 | if ( Node == NULL ) 496 | return -1; 497 | int nBlock = Node->u.m_color == NS_BLACK; 498 | return GetBlackNodeRight(Node->m_rchild) + nBlock; 499 | } 500 | 501 | bool RBTree3::_Check(TreeNode * Node) 502 | { 503 | if ( Node == NULL ) 504 | return true; 505 | 506 | int nLeft = GetBlackNodeLeft(Node->m_lchild); 507 | int nRight = GetBlackNodeRight(Node->m_rchild); 508 | 509 | // if ( Node == m_root ) 510 | // { 511 | // printf("Root left Black Node %d right Black Node %d \r\n",nLeft + 1, nRight + 1); 512 | // } 513 | 514 | if( nLeft != nRight) 515 | { 516 | printf("Data %d left Black Node %d != right Black Node %d \r\n", Node->m_Data, nLeft + 1, nRight + 1); 517 | return false; 518 | } 519 | 520 | if ( Node->u.m_color == NS_RED ) 521 | { 522 | if ( Node->m_lchild && Node->m_lchild->u.m_color == NS_RED ) 523 | { 524 | printf("double L red %d-->%d \r\n", Node->m_Data, Node->m_lchild->m_Data ); 525 | return false; 526 | } 527 | 528 | if ( Node->m_rchild && Node->m_rchild->u.m_color == NS_RED ) 529 | { 530 | printf("double R red %d-->%d \r\n", Node->m_Data, Node->m_rchild->m_Data ); 531 | return false; 532 | } 533 | } 534 | 535 | if ( _Check(Node->m_lchild) == false ) 536 | return false; 537 | 538 | if ( _Check(Node->m_rchild) == false ) 539 | return false; 540 | 541 | return true; 542 | } 543 | -------------------------------------------------------------------------------- /BalanceTree/RBTree2.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "RBTree2.h" 3 | 4 | #define NS_RBTREE_RECURSION2 5 | 6 | RBTree2::RBTree2(void) 7 | { 8 | } 9 | 10 | 11 | RBTree2::~RBTree2(void) 12 | { 13 | } 14 | 15 | TreeNode* RBTree2::SingleRotateWithLeft(TreeNode * Node) 16 | { 17 | TreeNode * mid = Node->m_lchild; 18 | Node->m_lchild = mid->m_rchild; 19 | mid->m_rchild = Node; 20 | 21 | return mid; 22 | } 23 | 24 | TreeNode* RBTree2::DoubleRotateWithLeft(TreeNode * Node) 25 | { 26 | TreeNode * mid = Node->m_lchild; 27 | TreeNode * tmp = mid->m_rchild; 28 | 29 | Node->m_lchild = tmp->m_rchild; 30 | mid->m_rchild = tmp->m_lchild; 31 | tmp->m_lchild = mid; 32 | tmp->m_rchild = Node; 33 | 34 | return tmp; 35 | } 36 | 37 | TreeNode* RBTree2::SingleRotateWithRight(TreeNode * Node) 38 | { 39 | TreeNode * mid = Node->m_rchild; 40 | 41 | Node->m_rchild = mid->m_lchild; 42 | mid->m_lchild = Node; 43 | 44 | return mid; 45 | } 46 | 47 | TreeNode* RBTree2::DoubleRotateWithRight(TreeNode * Node) 48 | { 49 | 50 | TreeNode * mid = Node->m_rchild; 51 | TreeNode * tmp = mid->m_lchild; 52 | 53 | Node->m_rchild = tmp->m_lchild; 54 | mid->m_lchild = tmp->m_rchild; 55 | 56 | tmp->m_lchild = Node; 57 | tmp->m_rchild = mid; 58 | 59 | return tmp; 60 | } 61 | 62 | bool RBTree2::Insert(T& Data) 63 | { 64 | bool bSign = true; 65 | bool bRet = _Insert(&m_root, Data, &bSign); 66 | if ( m_root ) 67 | m_root->u.m_color = NS_BLACK; 68 | return bRet; 69 | } 70 | 71 | bool RBTree2::_Insert(TreeNode ** ppNode, T& Data, bool * bSign) 72 | { 73 | bool bRet = false; 74 | TreeNode * pNode = *ppNode; 75 | if ( pNode == NULL ) 76 | { 77 | *ppNode = new(std::nothrow) TreeNode(Data); 78 | if ( *ppNode == NULL ) 79 | { 80 | *bSign = false; 81 | return false; 82 | } 83 | return true; 84 | } 85 | 86 | if ( Data < pNode->m_Data ) 87 | { 88 | bRet = _Insert(&pNode->m_lchild, Data, bSign ); 89 | if(*bSign) 90 | { 91 | TreeNode * mid = pNode->m_lchild; 92 | if ( mid->u.m_color == NS_RED ) 93 | { 94 | if ( IsLeftRed(mid) ) 95 | { 96 | if ( IsRightRed(pNode)) 97 | { 98 | SwapColor(pNode); 99 | } 100 | else 101 | { 102 | *ppNode = SingleRotateWithLeft(pNode); 103 | 104 | (*ppNode)->u.m_color = NS_BLACK; 105 | (*ppNode)->m_rchild->u.m_color = NS_RED; 106 | 107 | *bSign = false; 108 | } 109 | } 110 | else if ( IsRightRed(mid) ) 111 | { 112 | if ( IsRightRed(pNode)) 113 | { 114 | SwapColor(pNode); 115 | } 116 | else 117 | { 118 | *ppNode = DoubleRotateWithLeft(pNode); 119 | 120 | (*ppNode)->u.m_color = NS_BLACK; 121 | (*ppNode)->m_rchild->u.m_color = NS_RED; 122 | 123 | *bSign = false; 124 | } 125 | } 126 | } 127 | } 128 | } 129 | else if ( Data > pNode->m_Data ) 130 | { 131 | bRet = _Insert(&pNode->m_rchild, Data, bSign ); 132 | if(*bSign) 133 | { 134 | TreeNode * mid = pNode->m_rchild; 135 | if ( mid->u.m_color == NS_RED ) 136 | { 137 | if ( IsRightRed(mid) ) 138 | { 139 | if ( IsLeftRed(pNode)) 140 | { 141 | SwapColor(pNode); 142 | } 143 | else 144 | { 145 | *ppNode = SingleRotateWithRight(pNode); 146 | 147 | (*ppNode)->u.m_color = NS_BLACK; 148 | (*ppNode)->m_lchild->u.m_color = NS_RED; 149 | 150 | *bSign = false; 151 | } 152 | } 153 | else if ( IsLeftRed(mid) ) 154 | { 155 | if ( IsLeftRed(pNode)) 156 | { 157 | SwapColor(pNode); 158 | } 159 | else 160 | { 161 | *ppNode = DoubleRotateWithRight(pNode); 162 | 163 | (*ppNode)->u.m_color = NS_BLACK; 164 | (*ppNode)->m_lchild->u.m_color = NS_RED; 165 | 166 | *bSign = false; 167 | } 168 | } 169 | } 170 | } 171 | } 172 | else 173 | { 174 | *bSign = false; 175 | return false; 176 | } 177 | 178 | return bRet; 179 | } 180 | 181 | bool RBTree2::Delete(T& Data) 182 | { 183 | bool bSign = false; 184 | bool bRet = _Delete(&m_root, Data, &bSign); 185 | if ( m_root ) 186 | m_root->u.m_color = NS_BLACK; 187 | return bRet; 188 | } 189 | 190 | #ifndef NS_RBTREE_RECURSION2 191 | 192 | TreeNode * RBTree2::FixRotateWithLeft(TreeNode ** ppNode, bool * bSign) 193 | { 194 | TreeNode * pNode = *ppNode; 195 | TreeNode * mid = pNode->m_lchild; 196 | if ( mid->u.m_color == NS_BLACK ) 197 | { 198 | if ( IsLeftRed(mid) ) 199 | { 200 | *ppNode = SingleRotateWithLeft(pNode); 201 | 202 | (*ppNode)->u.m_color = (*ppNode)->m_rchild->u.m_color; 203 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 204 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 205 | 206 | *bSign = false; 207 | } 208 | else if ( IsRightRed(mid) ) 209 | { 210 | *ppNode = DoubleRotateWithLeft(pNode); 211 | 212 | (*ppNode)->u.m_color = (*ppNode)->m_rchild->u.m_color; 213 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 214 | 215 | *bSign = false; 216 | } 217 | else 218 | { 219 | mid->u.m_color = NS_RED; 220 | } 221 | } 222 | else 223 | { 224 | *ppNode = SingleRotateWithLeft(pNode); 225 | 226 | (*ppNode)->u.m_color = (*ppNode)->m_rchild->u.m_color; 227 | (*ppNode)->m_rchild->u.m_color = NS_RED; 228 | 229 | (*ppNode)->m_rchild = FixRotateWithLeft( &(*ppNode)->m_rchild, bSign); 230 | 231 | if ( *bSign && 232 | (*ppNode)->m_rchild->u.m_color == NS_RED ) 233 | { 234 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 235 | *bSign = false; 236 | } 237 | } 238 | 239 | return *ppNode; 240 | } 241 | 242 | TreeNode * RBTree2::FixRotateWithRight(TreeNode ** ppNode, bool * bSign) 243 | { 244 | TreeNode * pNode = *ppNode; 245 | TreeNode * mid = pNode->m_rchild; 246 | if ( mid->u.m_color == NS_BLACK ) 247 | { 248 | if ( IsRightRed(mid) ) 249 | { 250 | *ppNode = SingleRotateWithRight(pNode); 251 | 252 | (*ppNode)->u.m_color = (*ppNode)->m_lchild->u.m_color; 253 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 254 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 255 | 256 | *bSign = false; 257 | } 258 | else if ( IsLeftRed(mid) ) 259 | { 260 | *ppNode = DoubleRotateWithRight(pNode); 261 | 262 | (*ppNode)->u.m_color = (*ppNode)->m_lchild->u.m_color; 263 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 264 | 265 | *bSign = false; 266 | } 267 | else 268 | { 269 | mid->u.m_color = NS_RED; 270 | } 271 | } 272 | else 273 | { 274 | *ppNode = SingleRotateWithRight(pNode); 275 | 276 | (*ppNode)->u.m_color = (*ppNode)->m_lchild->u.m_color; 277 | (*ppNode)->m_lchild->u.m_color = NS_RED; 278 | 279 | (*ppNode)->m_lchild = FixRotateWithRight( &(*ppNode)->m_lchild, bSign); 280 | 281 | if ( *bSign && 282 | (*ppNode)->m_lchild->u.m_color == NS_RED ) 283 | { 284 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 285 | *bSign = false; 286 | } 287 | } 288 | 289 | return *ppNode; 290 | } 291 | 292 | #else 293 | 294 | TreeNode * RBTree2::FixRotateWithLeft(TreeNode ** ppNode, bool * bSign) 295 | { 296 | TreeNode * pNode = *ppNode; 297 | TreeNode * mid = pNode->m_lchild; 298 | if ( mid->u.m_color == NS_BLACK ) 299 | { 300 | if ( IsLeftRed(mid) ) 301 | { 302 | *ppNode = SingleRotateWithLeft(pNode); 303 | 304 | (*ppNode)->u.m_color = (*ppNode)->m_rchild->u.m_color; 305 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 306 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 307 | 308 | *bSign = false; 309 | } 310 | else if ( IsRightRed(mid) ) 311 | { 312 | *ppNode = DoubleRotateWithLeft(pNode); 313 | 314 | (*ppNode)->u.m_color = (*ppNode)->m_rchild->u.m_color; 315 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 316 | 317 | *bSign = false; 318 | } 319 | else 320 | { 321 | mid->u.m_color = NS_RED; 322 | } 323 | } 324 | else 325 | { 326 | *ppNode = SingleRotateWithLeft(pNode); 327 | 328 | (*ppNode)->u.m_color = (*ppNode)->m_rchild->u.m_color; 329 | (*ppNode)->m_rchild->u.m_color = NS_RED; 330 | 331 | (*ppNode)->m_rchild = FixRotateWithLeft( &(*ppNode)->m_rchild, bSign); 332 | } 333 | 334 | if ( *bSign && 335 | (*ppNode)->u.m_color == NS_RED ) 336 | { 337 | (*ppNode)->u.m_color = NS_BLACK; 338 | *bSign = false; 339 | } 340 | 341 | return *ppNode; 342 | } 343 | 344 | TreeNode * RBTree2::FixRotateWithRight(TreeNode ** ppNode, bool * bSign) 345 | { 346 | TreeNode * pNode = *ppNode; 347 | TreeNode * mid = pNode->m_rchild; 348 | if ( mid->u.m_color == NS_BLACK ) 349 | { 350 | if ( IsRightRed(mid) ) 351 | { 352 | *ppNode = SingleRotateWithRight(pNode); 353 | 354 | (*ppNode)->u.m_color = (*ppNode)->m_lchild->u.m_color; 355 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 356 | (*ppNode)->m_rchild->u.m_color = NS_BLACK; 357 | 358 | *bSign = false; 359 | } 360 | else if ( IsLeftRed(mid) ) 361 | { 362 | *ppNode = DoubleRotateWithRight(pNode); 363 | 364 | (*ppNode)->u.m_color = (*ppNode)->m_lchild->u.m_color; 365 | (*ppNode)->m_lchild->u.m_color = NS_BLACK; 366 | 367 | *bSign = false; 368 | } 369 | else 370 | { 371 | mid->u.m_color = NS_RED; 372 | } 373 | } 374 | else 375 | { 376 | *ppNode = SingleRotateWithRight(pNode); 377 | 378 | (*ppNode)->u.m_color = (*ppNode)->m_lchild->u.m_color; 379 | (*ppNode)->m_lchild->u.m_color = NS_RED; 380 | 381 | (*ppNode)->m_lchild = FixRotateWithRight( &(*ppNode)->m_lchild, bSign); 382 | } 383 | 384 | if ( *bSign && 385 | (*ppNode)->u.m_color == NS_RED ) 386 | { 387 | (*ppNode)->u.m_color = NS_BLACK; 388 | *bSign = false; 389 | } 390 | 391 | return *ppNode; 392 | } 393 | 394 | #endif 395 | 396 | 397 | 398 | bool RBTree2::_Delete(TreeNode ** ppNode, T& Data, bool * bSign) 399 | { 400 | bool bRet = false; 401 | TreeNode * pNode = *ppNode; 402 | if ( pNode == NULL ) 403 | return false; 404 | 405 | if ( Data < pNode->m_Data ) 406 | { 407 | bRet = _Delete(&pNode->m_lchild, Data, bSign); 408 | if ( *bSign ) 409 | { 410 | #ifndef NS_RBTREE_RECURSION2 411 | if ( pNode->m_lchild && 412 | pNode->m_lchild->u.m_color == NS_RED ) 413 | { 414 | pNode->m_lchild->u.m_color = NS_BLACK; 415 | *bSign = false; 416 | } 417 | else 418 | #else 419 | { 420 | *ppNode = FixRotateWithRight(ppNode, bSign); 421 | } 422 | #endif 423 | } 424 | } 425 | else if ( Data > pNode->m_Data ) 426 | { 427 | bRet = _Delete(&pNode->m_rchild, Data, bSign); 428 | if ( *bSign ) 429 | { 430 | #ifndef NS_RBTREE_RECURSION2 431 | if ( pNode->m_rchild && 432 | pNode->m_rchild->u.m_color == NS_RED ) 433 | { 434 | pNode->m_rchild->u.m_color = NS_BLACK; 435 | *bSign = false; 436 | } 437 | else 438 | #else 439 | { 440 | *ppNode = FixRotateWithLeft(ppNode, bSign); 441 | } 442 | #endif 443 | } 444 | } 445 | else 446 | { 447 | if ( pNode->m_rchild ) 448 | { 449 | TreeNode * tmp = FindMin( pNode->m_rchild ); 450 | pNode->m_Data = tmp->m_Data; 451 | 452 | bRet = _Delete(&pNode->m_rchild, pNode->m_Data, bSign); 453 | if ( *bSign ) 454 | { 455 | #ifndef NS_RBTREE_RECURSION2 456 | if ( pNode->m_rchild && 457 | pNode->m_rchild->u.m_color == NS_RED ) 458 | { 459 | pNode->m_rchild->u.m_color = NS_BLACK; 460 | *bSign = false; 461 | } 462 | else 463 | #else 464 | { 465 | *ppNode = FixRotateWithLeft(ppNode, bSign); 466 | } 467 | #endif 468 | } 469 | } 470 | else 471 | { 472 | TreeNode * tmp = pNode->m_lchild; 473 | 474 | if ( pNode->u.m_color == NS_BLACK ) 475 | *bSign = true; 476 | 477 | delete pNode; 478 | *ppNode = tmp; 479 | 480 | if ( tmp && tmp->u.m_color == NS_RED ) 481 | { 482 | tmp->u.m_color = NS_BLACK; 483 | *bSign = false; 484 | } 485 | 486 | bRet = true; 487 | } 488 | } 489 | 490 | return bRet; 491 | } 492 | 493 | bool RBTree2::Check() 494 | { 495 | if ( m_root && 496 | m_root->u.m_color != NS_BLACK ) 497 | return false; 498 | return _Check( m_root ); 499 | } 500 | 501 | int RBTree2::GetBlackNodeLeft(TreeNode * Node) 502 | { 503 | if ( Node == NULL ) 504 | return -1; 505 | int nBlock = Node->u.m_color == NS_BLACK; 506 | return GetBlackNodeLeft(Node->m_lchild) + nBlock; 507 | } 508 | 509 | int RBTree2::GetBlackNodeRight(TreeNode * Node) 510 | { 511 | if ( Node == NULL ) 512 | return -1; 513 | int nBlock = Node->u.m_color == NS_BLACK; 514 | return GetBlackNodeRight(Node->m_rchild) + nBlock; 515 | } 516 | 517 | bool RBTree2::_Check(TreeNode * Node) 518 | { 519 | if ( Node == NULL ) 520 | return true; 521 | 522 | int nLeft = GetBlackNodeLeft(Node->m_lchild); 523 | int nRight = GetBlackNodeRight(Node->m_rchild); 524 | 525 | // if ( Node == m_root ) 526 | // { 527 | // printf("Root left Black Node %d right Black Node %d \r\n",nLeft + 1, nRight + 1); 528 | // } 529 | 530 | if( nLeft != nRight) 531 | { 532 | printf("Data %d left Black Node %d != right Black Node %d \r\n", Node->m_Data, nLeft + 1, nRight + 1); 533 | return false; 534 | } 535 | 536 | if ( Node->u.m_color == NS_RED ) 537 | { 538 | if ( Node->m_lchild && Node->m_lchild->u.m_color == NS_RED ) 539 | { 540 | printf("double L red %d-->%d \r\n", Node->m_Data, Node->m_lchild->m_Data ); 541 | return false; 542 | } 543 | 544 | if ( Node->m_rchild && Node->m_rchild->u.m_color == NS_RED ) 545 | { 546 | printf("double R red %d-->%d \r\n", Node->m_Data, Node->m_rchild->m_Data ); 547 | return false; 548 | } 549 | } 550 | 551 | if ( _Check(Node->m_lchild) == false ) 552 | return false; 553 | 554 | if ( _Check(Node->m_rchild) == false ) 555 | return false; 556 | 557 | return true; 558 | } 559 | --------------------------------------------------------------------------------