标签:释放内存 旋转 dom 存在 ret front 左右 map lis
1 #ifndef _RBTREE_H_ 2 #define _RBTREE_H_ 3 4 const int nodeSize = 3; 5 class RBTree 6 { 7 private: 8 typedef struct Node { 9 int key; 10 int color; //0为红,1为黑 11 Node * family[nodeSize]; //family[0]左节点,family[1]右节点,family[2]父节点 12 Node(int k, int c); 13 }* Pnode; 14 private: 15 Pnode nil; 16 Pnode root; 17 private: 18 //返回k节点 19 Pnode __GetNode(int k); 20 //中序遍历 21 void __ShowNode(Pnode n)const; 22 //旋转节点,direction 为 0 左旋转,1右旋转 23 void __Rotate(Pnode n, int direction); 24 //修正插入后的红黑树 25 void __InsertFixup(Pnode n); 26 //修正删除后的红黑树 27 void __DeleteFixup(Pnode delNode); 28 //释放内存 29 void __Clear(Pnode n); 30 //返回当前节点(包含当前节点)下的所有节点个数. 31 size_t __NodeSize(Pnode n); 32 //返回节点n的前驱(direction = 0),后继(direction = 1) 33 Pnode __GetNeighbor(Pnode n, int direction); 34 public: 35 RBTree(); 36 bool IsExist(int k); 37 size_t Size(); 38 //按从小到大打印所有节点的key值 39 void ShowList()const; 40 //按树的层次打印节点的key值和颜色(R,B) 41 void ShowTree()const; 42 //插入新节点 43 void Insert(int k); 44 //删除节点 45 void Delete(int k); 46 ~RBTree(); 47 }; 48 49 #endif
1 #include "RBTree.h" 2 #include <iostream> 3 #include <queue> 4 5 using namespace std; 6 7 RBTree::Node::Node(int k = 0x80000000, int c = 0) :key(k), color(c), family{} {} 8 9 RBTree::RBTree(): nil(new Node(0x80000000, 1)), root(nil){} 10 11 RBTree::~RBTree() 12 { 13 __Clear(root); 14 delete nil; 15 } 16 17 void RBTree::__Clear(Pnode n) 18 { 19 if (n == nil) 20 return; 21 __Clear(n->family[0]); 22 __Clear(n->family[1]); 23 delete n; 24 } 25 26 bool RBTree::IsExist(int k) 27 { 28 return __GetNode(k) != nil; 29 } 30 31 size_t RBTree::__NodeSize(Pnode n) 32 { 33 if (n == nil) 34 return 0; 35 return 1 + __NodeSize(n->family[0]) + __NodeSize(n->family[1]); 36 } 37 38 void RBTree::__ShowNode(Pnode n) const 39 { 40 if (n == nil) 41 return; 42 __ShowNode(n->family[0]); 43 cout << n->key << " "; 44 __ShowNode(n->family[1]); 45 } 46 47 void RBTree::ShowList() const 48 { 49 __ShowNode(root); 50 cout << endl; 51 } 52 53 void RBTree::ShowTree() const 54 { 55 queue<Pnode> dn; 56 if(root != nil) 57 dn.push(root); 58 int size = 0; 59 while (!dn.empty()) 60 { 61 size = dn.size(); 62 for (int i = 0; i < size; i++) 63 { 64 cout << dn.front()->key; 65 if (dn.front()->color) 66 cout << "B "; 67 else cout << "R "; 68 if (dn.front()->family[0] != nil) 69 dn.push(dn.front()->family[0]); 70 if (dn.front()->family[1] != nil) 71 dn.push(dn.front()->family[1]); 72 dn.pop(); 73 } 74 cout << endl; 75 } 76 } 77 78 RBTree::Pnode RBTree::__GetNeighbor(Pnode n, int direction) 79 { 80 Pnode current{}; 81 if (n->family[direction] != nil) 82 { 83 current = n->family[direction]; 84 while (current->family[!direction] != nil) 85 current = current->family[!direction]; 86 } 87 else { 88 current = n; 89 while (current->family[2] != nil && current != current->family[2]->family[!direction]) 90 current = current->family[2]; 91 current = current->family[2]; 92 } 93 return current; 94 } 95 96 RBTree::Pnode RBTree::__GetNode(int k) 97 { 98 Pnode current = root; 99 while (current != nil) 100 { 101 if (current->key == k) 102 break; 103 else 104 current = current->family[k > current->key]; 105 } 106 return current; 107 } 108 109 //direction = 0 左转,1 右转 110 void RBTree::__Rotate(Pnode x, int direction) 111 { 112 Pnode y = x->family[!direction]; 113 x->family[!direction] = y->family[direction]; 114 if (y->family[direction]) 115 y->family[direction]->family[2] = x; 116 y->family[2] = x->family[2]; 117 if (x->family[2] == nil) 118 root = y; 119 else 120 x->family[2]->family[x == x->family[2]->family[1]] = y; 121 x->family[2] = y; 122 y->family[direction] = x; 123 } 124 125 void RBTree::__InsertFixup(Pnode n) 126 { 127 int plr = 0; 128 //如果n的父节点不为空,且父节点颜色为红色 129 while (!n->family[2]->color) 130 { 131 //如果n的父节点是祖父节点的左节点,则plr = 0,反之为1 132 plr = (n->family[2] == n->family[2]->family[2]->family[0] ? 0 : 1); 133 //如果存在叔节点,且叔节点颜色为红,则将父节点和叔结点颜色变黑,当前节点成为祖节点且颜色变红. 134 if ((n->family[2]->family[2]->family[!plr]) && 135 !(n->family[2]->family[2]->family[!plr]->color)) 136 { 137 n = n->family[2]->family[2]; 138 n->color = 0; 139 n->family[plr]->color = 1; 140 n->family[!plr]->color = 1; 141 } 142 else { 143 //如果n是左节点,则lr为0,反之为1 144 int lr = n == n->family[2]->family[0] ? 0 : 1; 145 //如果n是左节点,其父为右节点;或者n是右节点,其父为左节点 146 if (lr + plr == 1) 147 { 148 n = n->family[2]; 149 __Rotate(n, !lr); 150 //旋转后,n变为原来反方向的节点 151 lr = !lr; 152 } 153 n = n->family[2]->family[2]; 154 __Rotate(n, !lr); 155 n->color = 0; 156 n->family[2]->color = 1; 157 break; 158 } 159 } 160 root->color = 1; 161 } 162 163 void RBTree::Insert(int k) 164 { 165 Pnode current = root; 166 Pnode prev = nil; 167 while (current != nil) 168 { 169 prev = current; 170 if (k < current->key) 171 current = current->family[0]; 172 else if (k > current->key) 173 current = current->family[1]; 174 else { 175 cout << k << " is already exist!!!\n"; 176 return; 177 } 178 } 179 Pnode new_node = new Node(k); 180 new_node->family[0] = new_node->family[1] = nil; 181 new_node->family[2] = prev; 182 if (root == nil) 183 root = new_node; 184 else if (k < prev->key) 185 prev->family[0] = new_node; 186 else prev->family[1] = new_node; 187 __InsertFixup(new_node); 188 } 189 190 191 void RBTree::__DeleteFixup(Pnode delNode) 192 { 193 Pnode bakNode = delNode; 194 while (delNode != root && delNode->color) 195 { 196 //delNode如果是左孩子lr = 0, 反之lr = 1,为便于思考,假定lr=0,即delNode为左孩子. 197 int lr = delNode == delNode->family[2]->family[1]; 198 Pnode brother = delNode->family[2]->family[!lr]; 199 //如果兄弟结点颜色为红色,则其父结点和兄弟孩子的颜色必为黑,以父节点为轴左旋转重新着色后,delNode新兄弟结点颜色为黑 200 if (!brother->color) { 201 delNode->family[2]->color = 0; 202 brother->color = 1; 203 __Rotate(delNode->family[2], lr); 204 brother = delNode->family[2]->family[!lr]; 205 } 206 //如果兄弟左右孩子都为黑色,兄弟结点着红色,将父结点成为当前节点 207 if (brother->family[0]->color && brother->family[1]->color) { 208 brother->color = 0; 209 delNode = delNode->family[2]; 210 } 211 else { 212 //如果兄弟右孩子为黑色 213 if (brother->family[!lr]->color) { 214 brother->color = 0; 215 brother->family[lr]->color = 1; 216 __Rotate(brother, !lr); 217 brother = brother->family[2]; 218 } 219 brother->color = brother->family[2]->color; 220 brother->family[!lr]->color = 1; 221 brother->family[2]->color = 1; 222 __Rotate(brother->family[2], lr); 223 break; 224 } 225 } 226 delNode->color = 1; 227 //删除节点,释放内存 228 if (bakNode == root) 229 root = nil; 230 else if (bakNode == bakNode->family[2]->family[0]) 231 bakNode->family[2]->family[0] = nil; 232 else 233 bakNode->family[2]->family[1] = nil; 234 delete bakNode; 235 } 236 237 void RBTree::Delete(int k) 238 { 239 Pnode delNode = __GetNode(k); 240 if (delNode == nil) { 241 cout << k << "is not exist, delete failed!\n"; 242 return; 243 } 244 //如果有双子节点,找后继节点successor,则successor没有左子节点 245 if(delNode->family[0] != nil && delNode->family[1] != nil) 246 { 247 Pnode successor = __GetNeighbor(delNode, 0); 248 delNode->key = successor->key; 249 delNode = successor; 250 } 251 //如果没子节点 252 if (delNode->family[0] == nil && delNode->family[1] == nil) { 253 __DeleteFixup(delNode); 254 } 255 //如果仅有单子节点,那么delNode必为黑色,且其独生子女为红色 256 else{ 257 int lr = delNode->family[0] == nil; 258 delNode->key = delNode->family[lr]->key; 259 delete delNode->family[lr]; 260 delNode->family[lr] = nil; 261 } 262 } 263 264 size_t RBTree::Size() 265 { 266 return __NodeSize(root); 267 }
1 #define CRTDBG_MAP_ALLOC 2 #include "stdafx.h" 3 #include <crtdbg.h> 4 #include "RBTree.h" 5 #include <iostream> 6 #include <ctime> 7 8 using namespace std; 9 const int ASIZE = 10; 10 void LoadArrayToTree(RBTree & t, int * arr, int n); 11 void GetRandomArray(int * arr, int n); 12 void ShowArray(int * arr, int n); 13 void Show(RBTree & t); 14 void DeleteTree(RBTree &t, int * arr, int n); 15 16 int main() 17 { 18 { 19 srand(size_t(time(0))); 20 int arr[ASIZE]{11,26,35,14,5,26,57,8,39,10}; 21 //int arr[ASIZE]{}; 22 //GetRandomArray(arr, ASIZE); 23 ShowArray(arr, ASIZE); 24 RBTree t; 25 LoadArrayToTree(t, arr, ASIZE); 26 Show(t); 27 DeleteTree(t, arr, ASIZE); 28 Show(t); 29 } 30 //内存泄露测试 31 _CrtDumpMemoryLeaks(); 32 return 0; 33 } 34 35 //main test method 36 void LoadArrayToTree(RBTree & t, int * arr, int n) 37 { 38 for (int i = 0; i < n; i++) 39 t.Insert(arr[i]); 40 } 41 42 void DeleteTree(RBTree & t, int * arr, int n) 43 { 44 for (int i = 0; i < n; i++) 45 t.Delete(arr[i]); 46 } 47 48 void GetRandomArray(int * arr, int n) 49 { 50 for (int i = 0; i < n; i++) 51 { 52 arr[i] = rand()%50000+1; 53 //不重复数组 54 /*int num = rand() % 50000 + 1; 55 int j = 0; 56 for (j = 0; j < i; j++) 57 { 58 if (arr[j] == num) 59 break; 60 } 61 if (j == i) 62 arr[i] = num; 63 else --i;*/ 64 } 65 } 66 67 void ShowArray(int * arr, int n) 68 { 69 for (int i = 0; i < n; i++) 70 cout << arr[i] << " "; 71 cout << endl; 72 } 73 74 void Show(RBTree & t) 75 { 76 cout << "\nt.Size() = " << t.Size() << endl; 77 cout << "********************List**********************\n"; 78 t.ShowList(); 79 cout << "********************Tree**********************\n"; 80 t.ShowTree(); 81 cout << "********************End***********************\n"; 82 cout << endl; 83 } 84 // end of main test
标签:释放内存 旋转 dom 存在 ret front 左右 map lis
原文地址:http://www.cnblogs.com/endenvor/p/7774605.html