数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树

实验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 运行结果截图及说明

 数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第1张图片

图1 测试(1)①

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第2张图片

图2 测试(1)②

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第3张图片

图3 测试(2)①

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第4张图片

图4 测试(2)②

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第5张图片

图5 测试(3)

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第6张图片

图6 测试(4)

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第7张图片

图7 测试(5)①

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第8张图片

图8 测试(5)①

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第9张图片

图9 测试(5)①

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第10张图片

图10 测试(5)①

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第11张图片

图11 测试(5)②

 

 数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第12张图片

图12 测试(5)②

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第13张图片

图13 测试(5)②

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第14张图片

图14 测试(5)①(全)

 

数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树_第15张图片

图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 
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 
15 #include 
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, vectorVI/*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*/vectorVI )
 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     vectorVI;
 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     vectorVI;
 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     vectorVI;
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 
13 #include 
14 #include 
15 #include 
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* RR_Rotate(AVLNode *AVLB);        //rotate left
20                                                     //当在RR发生不平衡时需要进行左旋转
21     AVLNode* LL_Rotate(AVLNode *AVLB);        //rotate right
22                                                     //当在LL发生不平衡时需要进行右旋转
23     AVLNode* LR_Rotate(AVLNode *AVLB);    //rotate left then right
24     AVLNode* RL_Rotate(AVLNode *AVLB);    //rotate right then left
25     AVLNode* getRootNode();
26     void reBalance(AVLNode *AVLB);
27     int height(AVLNode *AVLB);
28     void setBalance(AVLNode *AVLB);
29     void printBalance(AVLNode *AVLB);
30     void clearNode(AVLNode *AVLB);
31     void inOrderTraverse(AVLNode *AVLB);
32     void preOrderTraverse(AVLNode *AVLB);
33     void postOrderTraverse(AVLNode *AVLB);
34 
35     void display(AVLNode *AVLB, int space, int colour);
36 
37 private:
38     AVLNode *root;
39 };

 

 1 #include "pch.h"
 2 #include "AVLnode.h"
 3 
 4 
 5 template <class T>
 6 AVLNode::~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::reBalance(AVLNode *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* AVLTree::RR_Rotate(AVLNode *AVLB)
 37 {
 38     AVLNode *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* AVLTree::LL_Rotate(AVLNode *AVLB)
 67 {
 68     AVLNode *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* AVLTree::LR_Rotate(AVLNode *AVLB)
 97 {
 98     AVLB->leftChild = RR_Rotate(AVLB->leftChild);
 99     return LL_Rotate(AVLB);
100 }
101 
102 template <class T>
103 AVLNode* AVLTree::RL_Rotate(AVLNode *AVLB)
104 {
105     AVLB->rightChild = LL_Rotate(AVLB->rightChild);
106     return RR_Rotate(AVLB);
107 }
108 
109 template <class T>
110 AVLNode* AVLTree::getRootNode()
111 {
112     return root;
113 }
114 
115 template <class T>
116 int AVLTree::height(AVLNode *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::setBalance(AVLNode *AVLB)
125 {
126     AVLB->balance = height(AVLB->rightChild) - height(AVLB->leftChild);
127 }
128 
129 template <class T>
130 void AVLTree::printBalance(AVLNode *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::inOrderTraverse(AVLNode *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::preOrderTraverse(AVLNode *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::postOrderTraverse(AVLNode *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::display(AVLNode *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::AVLTree(void) : root(NULL) {}
200 
201 template <class T>
202 AVLTree::~AVLTree(void)
203 {
204     delete root;
205 }
206 
207 template <class T>
208 bool AVLTree::insert(T key)
209 {
210     if (root == NULL)
211     {
212         root = new AVLNode(key, NULL);
213     }
214     else
215     {
216         AVLNode  //这种风格我觉得不错
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(key, parent);
236                 }
237                 else
238                 {
239                     parent->rightChild = new AVLNode(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::deleteKey(const T delKey)
253 {
254     if (root == NULL)
255         return;
256 
257     AVLNode
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::printBalance()
300 {
301     ios::sync_with_stdio(false);
302     printBalance(root);
303     cout << endl;
304 }
305 
306 template <class T>
307 void AVLTree::inOrderTraverse()
308 {
309     ios::sync_with_stdio(false);
310     inOrderTraverse(root);
311     cout << endl;
312 }
313 
314 template <class T>
315 void AVLTree::preOrderTraverse()
316 {
317     ios::sync_with_stdio(false);
318     preOrderTraverse(root);
319     cout << endl;
320 }
321 
322 template <class T>
323 void AVLTree::postOrderTraverse()
324 {
325     ios::sync_with_stdio(false);
326     postOrderTraverse(root);
327     cout << endl;
328 }
329 
330 template <class T>
331 void AVLTree::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 
  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 *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

 

你可能感兴趣的:(数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树)