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

     

    图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.
    Error 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!
    " << value << " is not in the binary search tree.
    " << "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!
    "; 
     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 << "
    ---------------------" << endl;
     39         cout << "AVL tree implementation" << endl;
     40         cout << "By Utah Xef developed" << endl;
     41         cout << "
    ---------------------" << 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
  • 相关阅读:
    angularJS---初识指令
    Bootstrap ACE后台管理界面模板-jquery已整理
    memcached和redis的区别和应用场景
    微信开发,公众号支付及微信扫描支付各自使用的密码分别来自哪里
    微信 redirect_uri参数错误 正确的处理
    jquery jsonp实现跨域
    php 常用的好函数(持续更新)
    pre 随变化的样式
    CSS 居中 可随着浏览器变大变小而居中
    2017.03.02-2017.09.28 日常随笔
  • 原文地址:https://www.cnblogs.com/25th-engineer/p/10105668.html
Copyright © 2020-2023  润新知