实验7
学号: 姓名: 专业:
7.1实验目的
(1) 掌握顺序表的查找方法,尤其是二分查找方法。
(2) 掌握二叉排序树的建立及查找。
查找是软件设计中的最常用的运算,查找所涉及到的表结构的不同决定了查找的方法及其性能。二分查找是顺序表的查找中的最重要的方法,应能充分理解其实现方法和有关性能,并能借助其判定树结构来加深理解。二叉排序树结构在实验时具有一定的难度,可结合二叉树的有关内容和方法来实现。
7.2 实验任务
编写算法实现下列问题的求解。
(1) 对下列数据表,分别采用二分查找算法实现查找,给出查找过程依次所比较的元素(的下标),并以二分查找的判定树来解释。
第一组测试数据:
数据表为 (1,2,3,4,6,7,8,9,10,11,12,13,17,18,19,20,24,25,26,30,35,40,45,50,100)
查找的元素分别为: 2,8,20, 30,50,5,15,33,110
第二组数据:
数据表为 (2,3,5,7,8,10,12,15,18,20,22,25,30,35,40,45,50,55,60, 80,100)
查找的元素分别为: 22,8,80,3,100,1,13,120
(2) 设计出在二叉排序树中插入结点的算法,在此基础上实现构建二叉排序树的算法。
测试数据:构建二叉排序树的输入序列如下:
第一组数据:
100,150,120,50,70,60,80,170,180,160,110,30,40,35,175
第二组数据:
100,70,60,80,150,120,50,160,30,40,170,180,175,35
(3) 设计算法在二叉排序树中查找指定值的结点。
测试数据:在任务<1>中第一组测试数据所构造的二叉排序树中,分别查找下列元素: 150,70,160,190,10,55,175
(4) 设计算法在二叉排序树中删除特定值的结点。
测试数据:在任务(1)中第一组测试数据所构造的二叉排序树中,分别删除下列元素:30,150,100
(5) 已知整型数组A[1..26]递增有序,设计算法以构造一棵平衡的二叉排序树来存放该数组中的所有元素。
测试数据:数组元素分别为:
第一组数据:
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26)
第二组数据:
(1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210,231,253,277,302,328)
7.3实验数据要求
自我编写测试样例,要求每个功能函数的测试样例不少于两组
7.4 运行结果截图及说明
图1 测试(1)①
图2 测试(1)②
图3 测试(2)①
图4 测试(2)②
图5 测试(3)
图6 测试(4)
图7 测试(5)①
图8 测试(5)①
图9 测试(5)①
图10 测试(5)①
图11 测试(5)②
图12 测试(5)②
图13 测试(5)②
图14 测试(5)①(全)
图15 测试(5)②(全)
7.5 附源代码
二分查找:
1 // stdafx.h : include file for standard system include files, 2 // or project specific include files that are used frequently, but 3 // are changed infrequently 4 // 5 6 #if !defined(AFX_STDAFX_H__940FF418_5647_412A_8B4F_3C89C07F8CA5__INCLUDED_) 7 #define AFX_STDAFX_H__940FF418_5647_412A_8B4F_3C89C07F8CA5__INCLUDED_ 8 9 #if _MSC_VER > 1000 10 #pragma once 11 #endif // _MSC_VER > 1000 12 13 14 #include <stdc++.h> 15 16 using namespace std; 17 18 typedef long elementType; 19 20 const long maxn = 10000 + 3; 21 22 // TODO: reference additional headers your program requires here 23 24 //{{AFX_INSERT_LOCATION}} 25 // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 26 27 #endif // !defined(AFX_STDAFX_H__940FF418_5647_412A_8B4F_3C89C07F8CA5__INCLUDED_)
1 // SeqList.h: interface for the SeqList class. 2 // 3 // 4 5 #if !defined(AFX_SEQLIST_H__58D90762_85EC_4BBB_94EA_068A582CCD81__INCLUDED_) 6 #define AFX_SEQLIST_H__58D90762_85EC_4BBB_94EA_068A582CCD81__INCLUDED_ 7 8 #if _MSC_VER > 1000 9 #pragma once 10 #endif // _MSC_VER > 1000 11 12 class SeqList 13 { 14 public: 15 SeqList(); 16 virtual ~SeqList(); 17 bool seqListFull(); 18 bool seqListEmpty(); 19 void randomInsert( elementType number ); 20 void insert( elementType value ); 21 void showLength(); 22 elementType binarySearch( elementType value ); 23 friend ostream &operator<<( ostream &os, SeqList &SL ) 24 { 25 if( SL.length == -1 ) 26 { 27 return os; 28 } 29 int column = 0; 30 for( int i = 1; i <= SL.length; i ++ ) 31 { 32 os << setw(6) << setiosflags( ios::left ) << SL.Arr[i] << " "; 33 column ++; 34 if( column % 10 == 0 ) 35 os << endl; 36 } 37 os << endl; 38 } 39 40 private: 41 elementType Arr[maxn]; 42 int length; 43 44 }; 45 46 #endif // !defined(AFX_SEQLIST_H__58D90762_85EC_4BBB_94EA_068A582CCD81__INCLUDED_)
1 // SeqList.cpp: implementation of the SeqList class. 2 // 3 // 4 5 #include "stdafx.h" 6 #include "SeqList.h" 7 8 // 9 // Construction/Destruction 10 // 11 12 SeqList::SeqList() 13 { 14 length = 0; 15 } 16 17 SeqList::~SeqList() 18 { 19 ios::sync_with_stdio(false); 20 cout << "The SeqList destruction has been called!" << endl; 21 } 22 23 bool SeqList::seqListFull() 24 { 25 return length == maxn - 1; 26 } 27 28 bool SeqList::seqListEmpty() 29 { 30 return length == 0; 31 } 32 33 void SeqList::randomInsert( elementType number ) 34 { 35 ios::sync_with_stdio(false); 36 if( seqListFull() ) 37 { 38 cerr << "Inserting failed!The sequence list has been full.Error in void SeqList::randomInsert( int number )" << endl; 39 return; 40 } 41 42 srand( time(NULL) ); 43 elementType last = -999; 44 for( int i = 0; i < number; i ++ ) 45 { 46 elementType key = rand() % ( 10000 - 100 + 1 ) + 100; 47 if( key >= last ) 48 { 49 length ++; 50 Arr[length] = key; 51 last = key; 52 } 53 else 54 { 55 i --; 56 } 57 } 58 } 59 60 void SeqList::insert( elementType value ) 61 { 62 ios::sync_with_stdio(false); 63 if( seqListFull() ) 64 { 65 cerr << "Inerting failed!The sequence list has been full.Error in void SeqList::insert( elementType value )" << endl; 66 return; 67 } 68 69 length ++; 70 Arr[length] = value; 71 } 72 73 elementType SeqList::binarySearch( elementType value ) 74 { 75 ios::sync_with_stdio(false); 76 if( seqListEmpty() ) 77 { 78 cerr << "Searching failed!The sequence list is empty.Error in elementType SeqList::binarySearch( elementType value )" << endl; 79 return -1; 80 } 81 elementType lower = 0, upper = length; 82 while( lower <= upper ) 83 { 84 elementType mid = ( lower + upper ) >> 1; //+ 1; 85 if( Arr[mid] == value ) 86 { 87 return mid; 88 } 89 if( Arr[mid] >= value ) 90 { 91 upper = mid - 1; 92 } 93 else 94 { 95 lower = mid + 1; 96 } 97 } 98 return -1; 99 } 100 101 void SeqList::showLength() 102 { 103 ios::sync_with_stdio(false); 104 cout << length << endl; 105 }
1 // BinarySearch.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "SeqList.h" 6 7 void test1() 8 { 9 ios::sync_with_stdio(false); 10 SeqList SL1; 11 elementType number; 12 cin >> number; 13 SL1.randomInsert( number ); 14 cout << SL1; 15 elementType value; 16 for( int i = 0; i < number; i ++ ) 17 { 18 cin >> value; 19 if( SL1.binarySearch(value) != -1 ) 20 { 21 cout << value << " is in the sequence list." << endl; 22 } 23 else 24 { 25 cout << value << " is not in the sequence list." << endl; 26 } 27 } 28 } 29 30 void test2() 31 { 32 ios::sync_with_stdio(false); 33 SeqList SL1; 34 elementType value; 35 while( cin >> value ) 36 { 37 if( value == -999 ) 38 { 39 break; 40 } 41 SL1.insert(value); 42 } 43 SL1.showLength(); 44 cout << SL1; 45 46 elementType key; 47 while( cin >> key ) 48 { 49 //cin >> key; 50 if( key == -99 ) 51 { 52 //break; 53 return; 54 } 55 if( SL1.binarySearch(key) != -1 ) 56 { 57 cout << key << " is in the sequence list." << endl; 58 } 59 else 60 { 61 cout << key << " is not in the sequence list." << endl; 62 } 63 } 64 65 } 66 67 int main(int argc, char* argv[]) 68 { 69 test2(); 70 71 return 0; 72 }
二分查找(排序)树:
1 // stdafx.h : include file for standard system include files, 2 // or project specific include files that are used frequently, but 3 // are changed infrequently 4 // 5 6 #if !defined(AFX_STDAFX_H__239FA301_F6C5_4AE4_BD82_5EB3365C7ECB__INCLUDED_) 7 #define AFX_STDAFX_H__239FA301_F6C5_4AE4_BD82_5EB3365C7ECB__INCLUDED_ 8 9 #if _MSC_VER > 1000 10 #pragma once 11 #endif // _MSC_VER > 1000 12 13 14 #include <stdc++.h> 15 #include <graphics.h> 16 17 using namespace std; 18 19 //将 elementType 设为 int 可以顺利完成实验要求;而将其设为 string 则可以输入字符串等, 20 //此时的大小关系默认为为字典序 21 //typedef string elementType; 22 typedef int elementType; 23 24 //为了图好玩,调用EasyX库把字体颜色改了一下 25 //这是EasyX的官方网站: https://www.easyx.cn/ 26 27 typedef struct node 28 { 29 elementType data; 30 struct node *leftChidld, *rightChild; 31 }BSTNode, *_BSTree; 32 33 // TODO: reference additional headers your program requires here 34 35 //{{AFX_INSERT_LOCATION}} 36 // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 37 38 #endif // !defined(AFX_STDAFX_H__239FA301_F6C5_4AE4_BD82_5EB3365C7ECB__INCLUDED_)
1 // BSTree.h: interface for the BSTree class. 2 // 3 // 4 5 #if !defined(AFX_BSTREE_H__37E371A7_E165_4AC3_898B_DDF38B0F87D8__INCLUDED_) 6 #define AFX_BSTREE_H__37E371A7_E165_4AC3_898B_DDF38B0F87D8__INCLUDED_ 7 8 #if _MSC_VER > 1000 9 #pragma once 10 #endif // _MSC_VER > 1000 11 12 class BSTree 13 { 14 public: 15 BSTree(); 16 virtual ~BSTree(); 17 BSTNode *search( _BSTree BST, elementType value );//递归查找 18 BSTNode *search( _BSTree BST, elementType value, _BSTree &father );//迭代查找 19 BSTNode *getRootNode(); 20 bool insert( _BSTree BST, elementType value ); 21 22 bool deleteNode1( _BSTree &BST, elementType value ); //删除指定结点,failed 23 void deleteNode2( _BSTree &BST, elementType value ); //递归删除指定结点 24 void deleteNode2_1( _BSTree &BST, elementType value ); //迭代删除指定结点,待调试! 25 void deleteNode3( _BSTree &BST, elementType value ); 26 27 void removeNode1( _BSTree &BST ); 28 void removeNode2( _BSTree &BST ); 29 void removeNode3( _BSTree &BST ); 30 31 void createBinarySearchTree( _BSTree BST, vector<elementType>VI/*elementType value*/ ); 32 void destroy( _BSTree BST ); 33 void preOrderTraversal( _BSTree BST/*, int space*/ ); 34 void inOrderTraversal( _BSTree BST/*, int space*/ ); 35 void postOrderTraversal( _BSTree BST/*, int space*/ ); 36 private: 37 BSTNode *head; 38 }; 39 40 #endif // !defined(AFX_BSTREE_H__37E371A7_E165_4AC3_898B_DDF38B0F87D8__INCLUDED_)
1 // BSTree.cpp: implementation of the BSTree class. 2 // 3 // 4 5 #include "stdafx.h" 6 #include "BSTree.h" 7 8 // 9 // Construction/Destruction 10 // 11 12 BSTree::BSTree() 13 { 14 //head = NULL; 15 //head = new BSTNode; 16 //head->leftChidld = head->rightChild = NULL; 17 } 18 19 BSTree::~BSTree() 20 { 21 ios::sync_with_stdio(false); 22 destroy(head); 23 cout << "The binary search tree has been destroyed!" << endl; 24 } 25 26 void BSTree::destroy( _BSTree BST ) 27 { 28 if(BST) 29 { 30 destroy( BST->leftChidld ); 31 destroy( BST->rightChild ); 32 delete BST; 33 } 34 } 35 36 void BSTree::preOrderTraversal( _BSTree BST/*, int space*/ ) 37 { 38 ios::sync_with_stdio(false); 39 /* 40 if(!BST) 41 { 42 cerr << "The binary search tree is empty.Error in void BSTree::preOrderTraversal( _BSTree BST )." << endl; 43 return; 44 } 45 */ 46 if(BST) 47 { 48 cout << BST->data << " "; 49 preOrderTraversal( BST->leftChidld ); 50 preOrderTraversal( BST->rightChild ); 51 52 //for( int i = 0; i < space; i ++ ) 53 // cout << " "; 54 //cout << BST->data << endl; 55 //preOrderTraversal( BST->leftChidld, space + 5 ); 56 //preOrderTraversal( BST->rightChild, space + 5 ); 57 } 58 } 59 60 void BSTree::inOrderTraversal( _BSTree BST/*, int space*/ ) 61 { 62 ios::sync_with_stdio(false); 63 if(BST) 64 { 65 inOrderTraversal( BST->leftChidld ); 66 cout << BST->data << " "; 67 inOrderTraversal( BST->rightChild ); 68 69 //inOrderTraversal( BST->leftChidld, space + 5 ); 70 //for( int i = 0; i < space; i ++ ) 71 // cout << " "; 72 //cout << BST->data << endl; 73 //inOrderTraversal( BST->rightChild, space + 5 ); 74 } 75 } 76 77 void BSTree::postOrderTraversal( _BSTree BST/*, int space*/ ) 78 { 79 ios::sync_with_stdio(false); 80 if(BST) 81 { 82 postOrderTraversal( BST->leftChidld ); 83 postOrderTraversal( BST->rightChild ); 84 cout << BST->data << " "; 85 86 /* 87 postOrderTraversal( BST->leftChidld, space + 5 ); 88 postOrderTraversal( BST->rightChild, space + 5 ); 89 for( int i = 0; i < space; i ++ ) 90 cout << " "; 91 cout << BST->data << endl; 92 */ 93 } 94 } 95 96 void BSTree::createBinarySearchTree( _BSTree BST, /*elementType value*/vector<elementType>VI ) 97 { 98 //BST = NULL; 99 head = NULL; 100 for( int i = 0; i < VI.size(); i ++ ) 101 { 102 insert( head, VI[i] ); 103 } 104 return; 105 /* 106 while( cin >> value ) 107 { 108 if( value == "#" ) 109 { 110 return; 111 } 112 else 113 insert( head, value ); 114 } 115 116 for( int i = 0; i < value; i ++ ) 117 { 118 elementType key; 119 cout << "input: "; 120 cin >> key; 121 insert( head, key ); 122 } 123 */ 124 } 125 126 BSTNode *BSTree::getRootNode() 127 { 128 return head; 129 } 130 131 BSTNode *BSTree::search( _BSTree BST, elementType value )//递归查找 132 { 133 ios::sync_with_stdio(false); 134 if(!head) 135 { 136 cerr << "The binary search tree is empty.Error in BSTNode *BSTree::search( _BSTree BST, elementType value )." << endl; 137 return NULL; 138 } 139 else if( BST->data == value ) 140 { 141 return BST; 142 } 143 else if( BST->data > value ) 144 { 145 return search( BST->leftChidld, value ); 146 } 147 else 148 { 149 return search( BST->rightChild, value ); 150 } 151 } 152 153 BSTNode *BSTree::search( _BSTree BST, elementType value, _BSTree &father )//迭代查找 154 { 155 ios::sync_with_stdio(false); 156 /* 157 if(!head) 158 { 159 cerr << "The binary search tree empty.Error in BSTNode *BSTree::search( _BSTree BST, elementType value, _BSTree &father )." << endl; 160 return NULL; 161 } 162 */ 163 BSTNode *tmp = head; 164 father = NULL; 165 while( tmp && tmp->data != value ) 166 { 167 father = tmp; 168 if( value < tmp->data ) 169 { 170 tmp = tmp->leftChidld; 171 } 172 else 173 { 174 tmp = tmp->rightChild; 175 } 176 } 177 return tmp; 178 } 179 180 bool BSTree::insert( _BSTree BST, elementType value ) 181 { 182 //if(!head) 183 //{ 184 // cerr << "The binary search tree does not exit.Error in bool BSTree::insert( _BSTree BST, elementType value )" << endl; 185 // return false; 186 //} 187 BSTNode *newNode, *target, *father; 188 189 target = search( head, value, father ); 190 if(target) 191 { 192 cerr << "Inserting failed!" << value << " has been exited in the binary search tree.\nError in bool BSTree::insert( _BSTree BST, elementType value )" << endl; 193 return false; 194 } 195 newNode = new BSTNode; 196 newNode->data = value; 197 newNode->leftChidld = newNode->rightChild = NULL; 198 if(!head) 199 { 200 head = newNode; 201 } 202 else if( value < father->data ) 203 { 204 father->leftChidld = newNode; 205 } 206 else 207 { 208 father->rightChild = newNode; 209 } 210 return true; 211 } 212 213 bool BSTree::deleteNode1( _BSTree &BST, elementType value ) 214 { 215 ios::sync_with_stdio(false); 216 //if(!head) 217 if(!BST) 218 { 219 cerr << "The binary search tree does not exit.Error in bool BSTree::deleteNode( _BSTree BST, elementType value )" << endl; 220 return false; 221 } 222 BSTNode *newNode, *target, *father; 223 //target = search( head, value, father ); 224 target = search( BST, value, father ); 225 if( !target )//查找失败,不删除 226 { 227 cerr << "Node-deleting failed!\n" << value << " is not in the binary search tree.\n" << "Error in bool BSTree::deleteNode( _BSTree BST, elementType value )." << endl; 228 return false; 229 } 230 if( target->leftChidld && target->rightChild )//被删结点有两个 *target 孩子节点 231 { 232 newNode = target->rightChild; //找 target 的中序后继 newNode 233 father = target; 234 while( newNode->leftChidld ) 235 { 236 father = newNode; 237 newNode = newNode->leftChidld; 238 } 239 target->data = newNode->data; //将 *newNode 的数据传給 *target 240 target = newNode; //找到的这个结点成为被删除结点 241 } 242 if( target->leftChidld ) //单孩子,记录非空孩子结点 243 { 244 newNode = target->leftChidld; 245 } 246 else 247 { 248 newNode = target->rightChild; 249 } 250 //if( target == head ) //被删结点是根结点 251 if( target == BST ) 252 { 253 //head = newNode; 254 BST = newNode; 255 } 256 else if( newNode && ( newNode->data < father->data ) ) //重新链接,保持二叉排序树 257 { 258 father->leftChidld = newNode; 259 } 260 else 261 { 262 father->rightChild = newNode; 263 } 264 delete target; 265 return true; 266 } 267 268 void BSTree::deleteNode2( _BSTree &BST, elementType value ) 269 { 270 if(BST) 271 { 272 if( value < BST->data ) 273 { 274 deleteNode2( BST->leftChidld, value ); 275 } 276 else if( value > BST->data ) 277 { 278 deleteNode2( BST->rightChild, value ); 279 } 280 else 281 { 282 removeNode1(BST); 283 } 284 } 285 } 286 287 void BSTree::deleteNode2_1( _BSTree &BST, elementType value ) //迭代删除指定结点,待调试! 288 { 289 BSTNode *target = NULL; 290 while( BST || BST->data != value ) 291 { 292 target = BST; 293 if( value < target->data ) 294 //if( value < BST->data ) 295 BST = BST->leftChidld; 296 else 297 BST = BST->rightChild; 298 } 299 removeNode1(target); 300 //removeNode1(BST); 301 } 302 303 void BSTree::deleteNode3( _BSTree &BST, elementType value ) 304 { 305 if(BST) 306 { 307 if( value < BST->data ) 308 { 309 deleteNode2( BST->leftChidld, value ); 310 } 311 else if( value > BST->data ) 312 { 313 deleteNode2( BST->rightChild, value ); 314 } 315 else 316 { 317 removeNode2(BST); 318 } 319 } 320 } 321 /* 322 在二叉查找树中删除一个给定的结点p有三种情况 323 324 (1)结点p无左右子树,则直接删除该结点,修改父节点相应指针 325 326 (2)结点p有左子树(右子树),则把p的左子树(右子树)接到p的父节点上 327 328 (3)左右子树同时存在,则有三种处理方式 329 330 a.找到结点p的中序直接前驱结点s,把结点s的数据转移到结点p,然后删除结点s, 331 由于结点s为p的左子树中最右的结点,因而s无右子树,删除结点s可以归结到情况(2)。 332 严蔚敏数据结构P230-231就是该处理方式。 333 b.找到结点p的中序直接后继结点s,把结点s的数据转移到结点p,然后删除结点s, 334 由于结点s为p的右子树总最左的结点,因而s无左子树,删除结点s可以归结到情况(2)。 335 算法导论第2版P156-157该是该处理方式。 336 c.到p的中序直接前驱s,将p的左子树接到父节点上,将p的右子树接到s的右子树上,然后删除结点p。 337 */ 338 void BSTree::removeNode1( _BSTree &BST ) 339 { 340 BSTNode *target = NULL; 341 if( !BST->leftChidld ) 342 { 343 target = BST; 344 BST = BST->rightChild; 345 delete target; 346 } 347 else if( !BST->rightChild ) 348 { 349 target = BST; 350 BST = BST->leftChidld; 351 delete target; 352 } 353 else 354 { 355 BSTNode *newNode = NULL; 356 target = BST; 357 newNode = BST->leftChidld; //左子树根结点 358 while( newNode->rightChild ) //寻找 BST 结点的中序前驱结点,即以 BST->leftChild为根结点的子树中的最右结点 359 { 360 target = newNode; //*target 指向 *BST 的父结点 361 newNode = newNode->rightChild; //*newNode 指向 *BST 的中序前驱结点 362 } 363 BST->data = newNode->data; //*newNode 的数据传給 *BST 的数据,然后删除结点 *newNode 364 if( target != BST ) //BST->leftChidld 的右子树非空,这句话等价于 if( !( target == BST ) ) 365 { 366 target->rightChild = newNode->leftChidld; //*newNode 的左子树接到 *target 的右子树上 367 } 368 else 369 { 370 target->leftChidld = newNode->leftChidld; //*newNode 的左子树接到 *target 的左子树上 371 } 372 delete newNode; //删除结点 *newNode 373 } 374 } 375 376 //注意 while 循环体: 377 //如果 BST 左子树为空,则 while 循环体不执行,那么 target 就不会发生改变。 378 //然而一开始 target == BST。 379 //反过来说,如果 BST 左子树不为空,则 while 执行,那么 target 就会发生改变。 380 //target 改变了,就和 BST 不一样。 381 //所以就可以表明 BST 左子树非空。 382 383 void BSTree::removeNode2( _BSTree &BST ) 384 { 385 BSTNode *target = NULL; 386 if( !BST->leftChidld ) 387 { 388 target = BST; 389 BST = BST->rightChild; 390 delete target; 391 } 392 else if( !BST->rightChild ) 393 { 394 target = BST; 395 BST = BST->leftChidld; 396 delete target; 397 } 398 else 399 { 400 BSTNode *newNode = NULL; 401 target = BST; 402 newNode = BST->rightChild; //右子树根结点 403 while( newNode->leftChidld ) //寻找 BST 结点的中序前驱结点,即以 BST->leftChild为根结点的子树中的最左结点 404 { 405 target = newNode; //*target 指向 *BST 的父结点 406 newNode = newNode->leftChidld; //*newNode 指向 *BST 的中序后继结点 407 } 408 BST->data = newNode->data; //*newNode 的数据传給 *BST 的数据,然后删除结点 *newNode 409 if( target != BST ) //BST->leftChidld 的左子树非空,这句话等价于 if( !( target == BST ) ) 410 { 411 target->leftChidld = newNode->rightChild; //*newNode 的右子树接到 *target 的左子树上 412 } 413 else 414 { 415 target->rightChild = newNode->rightChild; //*newNode 的右子树接到 *target 的右子树上 416 } 417 delete newNode; //删除结点 *newNode 418 } 419 } 420 421 //注意 while 循环体: 422 //如果 BST 右子树为空,则 while 循环体不执行,那么 target 就不会发生改变。 423 //然而一开始 target == BST。 424 //反过来说,如果 BST 右子树不为空,则 while 执行,那么 target 就会发生改变。 425 //target 改变了,就和 BST 不一样 426 //所以就可以表明 BST 右子树非空。 427 428 429 void BSTree::removeNode3( _BSTree &BST ) 430 { 431 BSTNode *target = NULL; 432 if( !BST->leftChidld ) 433 { 434 target = BST; 435 BST = BST->rightChild; 436 delete target; 437 } 438 else if( !BST->rightChild ) 439 { 440 target = BST; 441 BST = BST->leftChidld; 442 delete target; 443 } 444 else 445 { 446 BSTNode *newNode = NULL; 447 target = BST; 448 newNode = BST->leftChidld; //左子树根结点 449 while( newNode->rightChild ) //寻找 BST 结点的中序前驱结点,即以 BST->leftChild为根结点的子树中的最右结点 450 { 451 //target = newNode; 452 newNode = newNode->rightChild; 453 } 454 newNode->rightChild = target->leftChidld; //*target 的左子树接到 *newNode 的左子树上 455 target = target->leftChidld; //*target 的左子树接到父结点上 456 delete target; //删除结点 *target 457 } 458 }
1 // BinarySearchTree.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "BSTree.h" 6 7 //这是EasyX的官方网站: https://www.easyx.cn/ 8 9 void test1() 10 { 11 HANDLE hOut; 12 13 // 获取输出流的句柄 14 hOut = GetStdHandle(STD_OUTPUT_HANDLE); 15 16 BSTree BST1; 17 elementType value; 18 vector<elementType>VI; 19 while( cin >> value ) 20 { 21 if( (char)value == '#' && value != 35/*-999*/ ) //细节处理:一定要加 && value != 35,因为 # 的ASCII码是35, 22 { //不加的话在输入数字“35”而不是“#”时循环也会终止 23 break; 24 } 25 else 26 { 27 VI.push_back(value); 28 } 29 30 } 31 BST1.createBinarySearchTree( BST1.getRootNode(), VI ); 32 33 SetConsoleTextAttribute(hOut, 34 FOREGROUND_RED | // 前景色_红色 35 FOREGROUND_BLUE |// 前景色_蓝色 36 FOREGROUND_INTENSITY);// 加强 37 38 cout << "PreOrder:" << endl; 39 BST1.preOrderTraversal( BST1.getRootNode() ); 40 cout << endl; 41 cout << "InOrder:" << endl; 42 BST1.inOrderTraversal( BST1.getRootNode() ); 43 cout << endl; 44 cout << "PostOrder:" << endl; 45 BST1.postOrderTraversal( BST1.getRootNode() ); 46 cout << endl; 47 48 SetConsoleTextAttribute(hOut, 49 FOREGROUND_RED | // 前景色_红色 50 FOREGROUND_GREEN | // 前景色_绿色 51 FOREGROUND_BLUE ); // 前景色_蓝色 52 53 return; 54 } 55 56 void test2() 57 { 58 HANDLE hOut; 59 60 // 获取输出流的句柄 61 hOut = GetStdHandle(STD_OUTPUT_HANDLE); 62 63 BSTree BST1; 64 elementType value; 65 vector<elementType>VI; 66 67 while( cin >> value ) 68 { 69 if( (char)value == '#' && value != 35/*-999*/ ) //细节处理:一定要加 && value != 35,因为 # 的ASCII码是35, 70 { //不加的话在输入数字“35”而不是“#”时循环也会终止 71 break; 72 } 73 else 74 { 75 VI.push_back(value); 76 } 77 78 } 79 80 BST1.createBinarySearchTree( BST1.getRootNode(), VI ); 81 82 _BSTree index = NULL; 83 84 SetConsoleTextAttribute(hOut, 85 FOREGROUND_RED | // 前景色_红色 86 FOREGROUND_BLUE |// 前景色_蓝色 87 FOREGROUND_INTENSITY);// 加强 88 89 cout << "PreOrder:" << endl; 90 91 BST1.preOrderTraversal( BST1.getRootNode() ); 92 cout << endl; 93 cout << "InOrder:" << endl; 94 BST1.inOrderTraversal( BST1.getRootNode() ); 95 cout << endl; 96 cout << "PostOrder:" << endl; 97 BST1.postOrderTraversal( BST1.getRootNode() ); 98 cout << endl; 99 100 101 102 //elementType key = ;// = 545; 103 //下面这句话不会运行 104 //cin >> key; 105 106 elementType Arr[] = { 150, 70, 160, 190, 10, 55, 175 }; 107 108 for( int j = 0; j < sizeof(Arr) / sizeof(elementType); j ++ ) 109 { 110 if( BST1.search( BST1.getRootNode(), Arr[j], index ) ) 111 { 112 SetConsoleTextAttribute(hOut, 113 FOREGROUND_BLUE | // 前景色_蓝色 114 FOREGROUND_INTENSITY ); // 前景色_加强 115 cout << Arr[j] << " is in the binary search tree." << endl; 116 SetConsoleTextAttribute(hOut, 117 FOREGROUND_RED | // 前景色_红色 118 FOREGROUND_GREEN | // 前景色_绿色 119 FOREGROUND_BLUE ); // 前景色_蓝色 120 } 121 else 122 { 123 SetConsoleTextAttribute(hOut, 124 FOREGROUND_RED | // 前景色_红色 125 FOREGROUND_INTENSITY ); // 前景色_加强 126 cout << Arr[j] << " is not in the binary search tree." << endl; 127 SetConsoleTextAttribute(hOut, 128 FOREGROUND_RED | // 前景色_红色 129 FOREGROUND_GREEN | // 前景色_绿色 130 FOREGROUND_BLUE ); // 前景色_蓝色 131 } 132 } 133 134 //无法实现下面这样输入数值判断其是否存在 135 /* 136 BSTNode *father = NULL, *target = NULL; 137 138 elementType key; 139 while( cin >> key ) 140 { 141 //target = NULL; 142 if( (char)key == '#' && key != 35 ) 143 { 144 break; 145 } 146 else 147 target = BST1.search( BST1.getRootNode(), key, father ); 148 149 if(!target) 150 { 151 cout << "No!" << endl; 152 } 153 else 154 { 155 cout << "Yes!" << endl; 156 } 157 158 } 159 */ 160 161 return; 162 } 163 164 void test3() 165 { 166 HANDLE hOut; 167 168 // 获取输出流的句柄 169 hOut = GetStdHandle(STD_OUTPUT_HANDLE); 170 171 BSTree BST1; 172 elementType value; 173 vector<elementType>VI; 174 175 while( cin >> value ) 176 { 177 if( (char)value == '#' && value != 35/*-999*/ ) //细节处理:一定要加 && value != 35,因为 # 的ASCII码是35, 178 { //不加的话在输入数字“35”而不是“#”时循环也会终止 179 break; 180 } 181 else 182 { 183 VI.push_back(value); 184 } 185 186 } 187 188 BST1.createBinarySearchTree( BST1.getRootNode(), VI ); 189 190 _BSTree index = NULL; 191 192 SetConsoleTextAttribute(hOut, 193 FOREGROUND_BLUE | // 前景色_蓝色 194 FOREGROUND_INTENSITY ); // 前景色_加强 195 cout << "The origin binary search tree is as follow:" << endl; 196 SetConsoleTextAttribute(hOut, 197 FOREGROUND_RED | // 前景色_红色 198 FOREGROUND_BLUE |// 前景色_蓝色 199 FOREGROUND_INTENSITY);// 加强 200 201 cout << "PreOrder:" << endl; 202 203 BST1.preOrderTraversal( BST1.getRootNode() ); 204 cout << endl; 205 cout << "InOrder:" << endl; 206 BST1.inOrderTraversal( BST1.getRootNode() ); 207 cout << endl; 208 cout << "PostOrder:" << endl; 209 BST1.postOrderTraversal( BST1.getRootNode() ); 210 211 cout << endl; 212 213 214 215 elementType Arr[] = { 30, 150, 100 }; 216 for( int i = 0; i < sizeof(Arr) / sizeof(elementType); i ++ ) 217 { 218 _BSTree index = BST1.getRootNode(); 219 //BST1.deleteNode1( index, Arr[i] ); 220 BST1.deleteNode2( index, Arr[i] ); 221 SetConsoleTextAttribute(hOut, 222 FOREGROUND_BLUE | // 前景色_蓝色 223 FOREGROUND_INTENSITY ); // 前景色_加强 224 cout << "After deleting node " << Arr[i] << ", the current binary search tree is as follow:"<< endl; 225 226 SetConsoleTextAttribute(hOut, 227 FOREGROUND_RED | // 前景色_红色 228 FOREGROUND_BLUE |// 前景色_蓝色 229 FOREGROUND_INTENSITY);// 加强 230 231 cout << "PreOrder:" << endl; 232 233 BST1.preOrderTraversal( BST1.getRootNode() ); 234 cout << endl; 235 cout << "InOrder:" << endl; 236 BST1.inOrderTraversal( BST1.getRootNode() ); 237 cout << endl; 238 cout << "PostOrder:" << endl; 239 BST1.postOrderTraversal( BST1.getRootNode() ); 240 cout << endl; 241 242 } 243 SetConsoleTextAttribute(hOut, 244 FOREGROUND_RED | // 前景色_红色 245 FOREGROUND_GREEN | // 前景色_绿色 246 FOREGROUND_BLUE ); // 前景色_蓝色 247 return; 248 } 249 250 251 int main(int argc, char* argv[]) 252 { 253 //test1(); 254 //test2(); 255 test3(); 256 return 0; 257 }
AVL树:
1 // Tips for Getting Started: 2 // 1. Use the Solution Explorer window to add/manage files 3 // 2. Use the Team Explorer window to connect to source control 4 // 3. Use the Output window to see build output and other messages 5 // 4. Use the Error List window to view errors 6 // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 7 // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 8 9 #ifndef PCH_H 10 #define PCH_H 11 12 #include <iostream> 13 #include <algorithm> 14 #include <graphics.h> 15 #include <windows.h> 16 17 using namespace std; 18 19 // TODO: add headers that you want to pre-compile here 20 21 #endif //PCH_H
1 #pragma once 2 /* AVL node */ 3 template <class T> 4 class AVLNode 5 { 6 public: 7 T key; 8 int balance; 9 AVLNode *leftChild, *rightChild, *parent; 10 11 AVLNode(T k, AVLNode *p) : key(k), balance(0), parent(p),leftChild(NULL), rightChild(NULL) {} 12 ~AVLNode(); 13 };
1 #pragma once 2 /* AVL tree */ 3 4 #include "AVLnode.h" 5 template <class T> 6 class AVLTree 7 { 8 public: 9 AVLTree(void); 10 ~AVLTree(void); 11 bool insert(T key); 12 void deleteKey(const T key); 13 void printBalance(); 14 void inOrderTraverse(); 15 void preOrderTraverse(); 16 void postOrderTraverse(); 17 void display(); 18 19 AVLNode<T>* RR_Rotate(AVLNode<T> *AVLB); //rotate left 20 //当在RR发生不平衡时需要进行左旋转 21 AVLNode<T>* LL_Rotate(AVLNode<T> *AVLB); //rotate right 22 //当在LL发生不平衡时需要进行右旋转 23 AVLNode<T>* LR_Rotate(AVLNode<T> *AVLB); //rotate left then right 24 AVLNode<T>* RL_Rotate(AVLNode<T> *AVLB); //rotate right then left 25 AVLNode<T>* getRootNode(); 26 void reBalance(AVLNode<T> *AVLB); 27 int height(AVLNode<T> *AVLB); 28 void setBalance(AVLNode<T> *AVLB); 29 void printBalance(AVLNode<T> *AVLB); 30 void clearNode(AVLNode<T> *AVLB); 31 void inOrderTraverse(AVLNode<T> *AVLB); 32 void preOrderTraverse(AVLNode<T> *AVLB); 33 void postOrderTraverse(AVLNode<T> *AVLB); 34 35 void display(AVLNode <T>*AVLB, int space, int colour); 36 37 private: 38 AVLNode<T> *root; 39 };
1 #include "pch.h" 2 #include "AVLnode.h" 3 4 5 template <class T> 6 AVLNode<T>::~AVLNode() 7 { 8 delete leftChild; 9 delete rightChild; 10 }
1 #include "pch.h" 2 #include "AVLtree.h" 3 4 5 template <class T> 6 void AVLTree<T>::reBalance(AVLNode<T> *AVLB) 7 { 8 setBalance(AVLB); 9 10 if (AVLB->balance == -2) 11 { 12 if (height(AVLB->leftChild->leftChild) >= height(AVLB->leftChild->rightChild)) 13 AVLB = LL_Rotate(AVLB); 14 else 15 AVLB = LR_Rotate(AVLB); 16 } 17 else if (AVLB->balance == 2) 18 { 19 if (height(AVLB->rightChild->rightChild) >= height(AVLB->rightChild->leftChild)) 20 AVLB = RR_Rotate(AVLB); 21 else 22 AVLB = RL_Rotate(AVLB); 23 } 24 25 if (AVLB->parent != NULL) 26 { 27 reBalance(AVLB->parent); 28 } 29 else 30 { 31 root = AVLB; 32 } 33 } 34 35 template <class T> 36 AVLNode<T>* AVLTree<T>::RR_Rotate(AVLNode<T> *AVLB) 37 { 38 AVLNode<T> *tmp = AVLB->rightChild; 39 tmp->parent = AVLB->parent; 40 AVLB->rightChild = tmp->leftChild; 41 42 if (AVLB->rightChild != NULL) 43 AVLB->rightChild->parent = AVLB; 44 45 tmp->leftChild = AVLB; 46 AVLB->parent = tmp; 47 48 if (tmp->parent != NULL) 49 { 50 if (tmp->parent->rightChild == AVLB) 51 { 52 tmp->parent->rightChild = tmp; 53 } 54 else 55 { 56 tmp->parent->leftChild = tmp; 57 } 58 } 59 60 setBalance(AVLB); 61 setBalance(tmp); 62 return tmp; 63 } 64 65 template <class T> 66 AVLNode<T>* AVLTree<T>::LL_Rotate(AVLNode<T> *AVLB) 67 { 68 AVLNode<T> *tmp = AVLB->leftChild; 69 tmp->parent = AVLB->parent; 70 AVLB->leftChild = tmp->rightChild; 71 72 if (AVLB->leftChild != NULL) 73 AVLB->leftChild->parent = AVLB; 74 75 tmp->rightChild = AVLB; 76 AVLB->parent = tmp; 77 78 if (tmp->parent != NULL) 79 { 80 if (tmp->parent->rightChild == AVLB) 81 { 82 tmp->parent->rightChild = tmp; 83 } 84 else 85 { 86 tmp->parent->leftChild = tmp; 87 } 88 } 89 90 setBalance(AVLB); 91 setBalance(tmp); 92 return tmp; 93 } 94 95 template <class T> 96 AVLNode<T>* AVLTree<T>::LR_Rotate(AVLNode<T> *AVLB) 97 { 98 AVLB->leftChild = RR_Rotate(AVLB->leftChild); 99 return LL_Rotate(AVLB); 100 } 101 102 template <class T> 103 AVLNode<T>* AVLTree<T>::RL_Rotate(AVLNode<T> *AVLB) 104 { 105 AVLB->rightChild = LL_Rotate(AVLB->rightChild); 106 return RR_Rotate(AVLB); 107 } 108 109 template <class T> 110 AVLNode<T>* AVLTree<T>::getRootNode() 111 { 112 return root; 113 } 114 115 template <class T> 116 int AVLTree<T>::height(AVLNode<T> *AVLB) 117 { 118 if (AVLB == NULL) 119 return -1; 120 return 1 + max(height(AVLB->leftChild), height(AVLB->rightChild)); 121 } 122 123 template <class T> 124 void AVLTree<T>::setBalance(AVLNode<T> *AVLB) 125 { 126 AVLB->balance = height(AVLB->rightChild) - height(AVLB->leftChild); 127 } 128 129 template <class T> 130 void AVLTree<T>::printBalance(AVLNode<T> *AVLB) 131 { 132 ios::sync_with_stdio(false); 133 if (AVLB != NULL) 134 { 135 printBalance(AVLB->leftChild); 136 cout << AVLB->balance << " "; 137 //std::cout << n->key << " "; 138 printBalance(AVLB->rightChild); 139 } 140 } 141 142 template <class T> 143 void AVLTree<T>::inOrderTraverse(AVLNode<T> *AVLB) 144 { 145 ios::sync_with_stdio(false); 146 if (AVLB) 147 { 148 inOrderTraverse(AVLB->leftChild); 149 cout << AVLB->key << " "; 150 inOrderTraverse(AVLB->rightChild); 151 } 152 } 153 154 template <class T> 155 void AVLTree<T>::preOrderTraverse(AVLNode<T> *AVLB) 156 { 157 if (AVLB) 158 { 159 cout << AVLB->key << " "; 160 preOrderTraverse(AVLB->leftChild); 161 preOrderTraverse(AVLB->rightChild); 162 } 163 } 164 165 template <class T> 166 void AVLTree<T>::postOrderTraverse(AVLNode<T> *AVLB) 167 { 168 ios::sync_with_stdio(false); 169 if (AVLB) 170 { 171 postOrderTraverse(AVLB->leftChild); 172 postOrderTraverse(AVLB->rightChild); 173 cout << AVLB->key << " "; 174 } 175 } 176 177 template <class T> 178 void AVLTree<T>::display(AVLNode <T>*AVLB, int space, int colour ) 179 { 180 ios::sync_with_stdio(false); 181 HANDLE hConsole; 182 hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 183 if (AVLB) 184 { 185 display(AVLB->rightChild, space + 1, colour + 1); 186 SetConsoleTextAttribute(hConsole, 0x0008 | colour); 187 //colour++; 188 cout << endl; 189 if (AVLB == root) 190 cout << " Root ----> "; 191 for (int i = 0; i < space && AVLB != root; i++) 192 cout << " "; 193 cout << AVLB->key; 194 display(AVLB->leftChild, space + 1, colour + 1); 195 } 196 } 197 198 template <class T> 199 AVLTree<T>::AVLTree(void) : root(NULL) {} 200 201 template <class T> 202 AVLTree<T>::~AVLTree(void) 203 { 204 delete root; 205 } 206 207 template <class T> 208 bool AVLTree<T>::insert(T key) 209 { 210 if (root == NULL) 211 { 212 root = new AVLNode<T>(key, NULL); 213 } 214 else 215 { 216 AVLNode<T> //这种风格我觉得不错 217 //I appreciate this style of code 218 *target = root, 219 *parent; 220 221 while (1) 222 { 223 if (target->key == key) 224 return false; 225 226 parent = target; 227 228 bool goLeft = target->key > key; 229 target = goLeft ? target->leftChild : target->rightChild; 230 231 if (target == NULL) 232 { 233 if (goLeft) 234 { 235 parent->leftChild = new AVLNode<T>(key, parent); 236 } 237 else 238 { 239 parent->rightChild = new AVLNode<T>(key, parent); 240 } 241 242 reBalance(parent); 243 break; 244 } 245 } 246 } 247 248 return true; 249 } 250 251 template <class T> 252 void AVLTree<T>::deleteKey(const T delKey) 253 { 254 if (root == NULL) 255 return; 256 257 AVLNode<T> 258 *target = root, 259 *parent = root, 260 *delNode = NULL, 261 *child = root; 262 263 while (child != NULL) 264 { 265 parent = target; 266 target = child; 267 child = delKey >= target->key ? target->rightChild : target->leftChild; 268 if (delKey == target->key) 269 delNode = target; 270 } 271 272 if (delNode != NULL) 273 { 274 delNode->key = target->key; 275 276 child = target->leftChild != NULL ? target->leftChild : target->rightChild; 277 278 if (root->key == delKey) 279 { 280 root = child; 281 } 282 else 283 { 284 if (parent->leftChild == target) 285 { 286 parent->leftChild = child; 287 } 288 else 289 { 290 parent->rightChild = child; 291 } 292 293 reBalance(parent); 294 } 295 } 296 } 297 298 template <class T> 299 void AVLTree<T>::printBalance() 300 { 301 ios::sync_with_stdio(false); 302 printBalance(root); 303 cout << endl; 304 } 305 306 template <class T> 307 void AVLTree<T>::inOrderTraverse() 308 { 309 ios::sync_with_stdio(false); 310 inOrderTraverse(root); 311 cout << endl; 312 } 313 314 template <class T> 315 void AVLTree<T>::preOrderTraverse() 316 { 317 ios::sync_with_stdio(false); 318 preOrderTraverse(root); 319 cout << endl; 320 } 321 322 template <class T> 323 void AVLTree<T>::postOrderTraverse() 324 { 325 ios::sync_with_stdio(false); 326 postOrderTraverse(root); 327 cout << endl; 328 } 329 330 template <class T> 331 void AVLTree<T>::display() 332 { 333 ios::sync_with_stdio(false); 334 int color = 1; 335 display(root, 1, color); 336 cout << endl; 337 }
1 // AVL_2.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 // 3 4 #include "pch.h" 5 #include <iostream> 6 #include "AVLtree.h" 7 #include "AVLnode.h" 8 #include "AVLnode.cpp" 9 #include "AVLtree.cpp" 10 11 int main() 12 { 13 //std::cout << "Hello World!\n"; 14 ios::sync_with_stdio(false); 15 AVLTree<int> AVLBT; 16 HANDLE hConsole; 17 hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 18 cout << "Inserting integer values 1 to 26" << std::endl; 19 int Arr[] = { 1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210,231, 20 253,277,302,328 }; 21 for (int i = 0; i < sizeof(Arr) / sizeof(int); i++) 22 //for( int i = 0; Arr[i] != 0; i ++ ) 23 //AVLBT.insert(i); 24 AVLBT.insert(Arr[i]); 25 26 cout << "Printing the balance factor of each node: " << std::endl; 27 SetConsoleTextAttribute(hConsole, 12); 28 AVLBT.printBalance(); 29 SetConsoleTextAttribute(hConsole, 7); 30 cout << "Printing key: " << std::endl; 31 SetConsoleTextAttribute(hConsole, 0x0008 | 8); 32 AVLBT.inOrderTraverse(); 33 AVLBT.display(); 34 //AVLTree<int> *root = avl.getRootNode(); 35 while (1) 36 { 37 SetConsoleTextAttribute(hConsole, 7); 38 cout << "\n---------------------" << endl; 39 cout << "AVL tree implementation" << endl; 40 cout << "By Utah Xef developed" << endl; 41 cout << "\n---------------------" << endl; 42 cout << "1.insert element into the tree" << endl; 43 cout << "2.display balanced AVL tree" << endl; 44 cout << "3.preorder traversal" << endl; 45 cout << "4.inorder traversal" << endl; 46 cout << "5.postorder traversal" << endl; 47 cout << "6.delete key" << endl; 48 cout << "7.display the balance factor of each node" << endl; 49 cout << "8.exit" << endl; 50 cout << "enter your choice: "; 51 int choice; 52 cin >> choice; 53 54 switch (choice) 55 56 { 57 58 case 1: 59 60 cout << "enter value to be inserted: "; 61 int item; 62 cin >> item; 63 64 AVLBT.insert(item); 65 66 break; 67 68 case 2: 69 70 if (AVLBT.getRootNode() == nullptr) 71 72 { 73 74 cout << "tree is empty" << endl; 75 76 continue; 77 78 } 79 80 cout << "balanced avl tree:" << endl; 81 82 AVLBT.display(); 83 84 break; 85 86 case 3: 87 88 cout << "preorder traversal:" << endl; 89 SetConsoleTextAttribute(hConsole, 0x0008 | 9); 90 AVLBT.preOrderTraverse(); 91 92 cout << endl; 93 94 break; 95 case 4: 96 97 cout << "inorder traversal:" << endl; 98 SetConsoleTextAttribute(hConsole, 0x0008 | 10); 99 AVLBT.inOrderTraverse(); 100 101 cout << endl; 102 103 break; 104 105 106 107 case 5: 108 109 cout << "postorder traversal:" << endl; 110 SetConsoleTextAttribute(hConsole, 0x0008 | 11); 111 AVLBT.postOrderTraverse(); 112 113 cout << endl; 114 115 break; 116 117 case 6: 118 int value; 119 cout << "Please input the value to delete:" << endl; 120 cin >> value; 121 AVLBT.deleteKey(value); 122 break; 123 124 case 7: 125 cout << "The balance factor of each node:" << endl; 126 SetConsoleTextAttribute(hConsole, 0x0008 | 14); 127 AVLBT.printBalance(); 128 break; 129 case 8: 130 exit(1); 131 132 break; 133 default: 134 135 cout << "Wrong choice" << endl; 136 break; 137 } 138 139 } 140 //std::cout << std::endl; 141 std::cin.get(); 142 } 143 144 // Run program: Ctrl + F5 or Debug > Start Without Debugging menu 145 // Debug program: F5 or Debug > Start Debugging menu 146 147 // Tips for Getting Started: 148 // 1. Use the Solution Explorer window to add/manage files 149 // 2. Use the Team Explorer window to connect to source control 150 // 3. Use the Output window to see build output and other messages 151 // 4. Use the Error List window to view errors 152 // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 153 // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file