zoukankan      html  css  js  c++  java
  • 数据结构实验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
  • 相关阅读:
    Fix Installing .NET Framework 3.5 failed Error Code 0x800F0954 on Windows 10
    RHEL8安装五笔输入法
    Enable EPEL and Local Repository on RHEL8
    Why is Yum Replaced by DNF?
    检查Linux服务器是否被攻击的常用命令及方法
    IDEA 主题
    IDEA 如何显示一个类中所有的方法
    Appium 安装以及安装过程中遇到的问题
    Maven 如何发布 jar 包到 Nexus 私库
    java泛型的基本使用
  • 原文地址:https://www.cnblogs.com/25th-engineer/p/10105668.html
Copyright © 2011-2022 走看看