问题六十四:怎么用C++实现二叉查找树(binary search tree)及其相关操作

64.0 概述

什么是二叉查找树(binary search tree)?

二叉查找树(binary search tree)又叫二叉排序树(binary ordered tree)。

对于任意二叉查找树,要么是一棵空树,要么具有如下性质:

若它的左子树不为空,则左子树上所有结点的值都小于它的根结点的值;

若它的右子树不为空,则右子树上所有结点的值都大于它的根结点的值;

它的左、右子树也分别为二叉查找树;

中序遍历二叉查找树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉查找树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程;

 

我们这里用到的二叉查找树的数据部分的数据类型为整型,如下代码为int定义一个别名“ItemType”:

typedef int ItemType;


如下代码是定义二叉查找树结点。每一个结点包含:数据部分,左孩子指针,右孩子指针。

struct TreeNode
{
    ItemType info;
    TreeNode* left;
    TreeNode* right;
};

 

如下定义二叉查找树类:定义伊始,是一棵空树。

class TreeType {// binary search tree.
    public:
        TreeType() {
            root = NULL;
        }
//在这个位置添加二叉查找树的各种操作方法的声明;
        TreeNode *root;
};

 

新建二叉查找树对象:

         TreeType binarySearchTree;

64.1 建立二叉查找树


下面,我们在已经定义的空的二叉查找树的基础上,建立有数据的树。

 

我们的做法是:将如下数组中的15个数据,依次建立二叉查找树。(相当于将数组中数据依次插入之前新建的空的二叉查找树)

         ItemType infoArray[15] = {20, 12, 2, 14, 15, 35, 6, 45, 25, 23, 1, 24, 16, 57, 28};

根据二叉查找树的定义和性质,如上数组中的15个数据对应的二叉查找树如下:

算法:

1,第一个被插入的数据(20)成为二叉查找树的根结点;

2,有了根结点之后,后面的数据被插入的位置取决于其与根结点值的大小关系:比根结点的值小,则在根结点的左子树中;比根结点的值大,则在根结点的右子树中。所以,关键是找到被插入数据未来的父结点。这样的父结点需要满足两个条件:其一,其值满足如上的大小关系;其二,其对应的左孩子结点或者右孩子结点(左、右由值的大小关系决定)的位置是空的。

 

对应C++代码如下:


----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        void CreateTree(ItemType *itemArray, int itemNum);


----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

void TreeType::CreateTree(ItemType *itemArray, int itemNum) {
     for(int i=0; i<itemNum; i++) {
         TreeNode *newnode = new TreeNode;
         newnode->info = itemArray[i];
         newnode->left = NULL;
         newnode->right = NULL;
         if(root == NULL) {
             root = newnode;
             std::cout << itemArray[i] << " will be the root" << endl;
         }
         else {
             TreeNode *parent;
             TreeNode *temp = root;
             while(temp != NULL) {//这个循环是找未来的父结点。
                 parent = temp;
                 if((temp->info) > itemArray[i]) {
                     temp = temp->left;
                 }
                 else {
                     temp = temp->right;
                 }
             }

             if((parent->info) > itemArray[i]) {
//这个if……else……是根据被插入值和父结点的大小关系,确定被插入的位置
                 parent->left = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s left child" << endl;
             }
             else {
                 parent->right = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s right child" << endl;
             }
         }
    }
}

 

----------------------------------------------main.cpp------------------------------------------

main.cpp

         TreeType binarySearchTree;
         ItemType infoArray[15] = {20, 12, 2, 14, 15, 35, 6, 45, 25, 23, 1, 24, 16, 57, 28};
         std::cout << "CreateTree: " << endl;
         binarySearchTree.CreateTree(infoArray, 15);
         std::cout << endl;

 

输出结果如下:

64.2 遍历二叉查找树


我们在“64.1”中建立了一棵二叉查找树,现在我们想看看这个树中每个结点的内容。我们需要遍历这个二叉查找树。

有三种遍历二叉查找树的方式:(根)前序遍历、(根)中序遍历、(根)后序遍历

如上二叉查找树的(根)前序遍历的结果应该是:20, 12, 2, 1, 6, 14, 15, 16, 35, 25, 23, 24, 28, 45, 57

如上二叉查找树的(根)前序遍历的结果应该是:1, 2, 6, 12, 14, 15, 16, 20, 23, 24, 25, 28, 35, 45, 57

如上二叉查找树的(根)前序遍历的结果应该是:1, 6, 2, 16, 15, 14, 12, 24, 23, 28, 25, 57, 45, 35, 20

 

我们采用递归的方法来完成遍历。

 

C++代码如下:


----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        void PreorderTraverse(TreeNode *rootNode);//(根)前序遍历
        void InorderTraverse(TreeNode *rootNode); //(根)中序遍历
        void PostorderTraverse(TreeNode *rootNode); //(根)后序遍历


----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

void TreeType::PreorderTraverse(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         std::cout << rootNode->info << " ";//遍历根结点
         PreorderTraverse(rootNode->left);//遍历左子树
         PreorderTraverse(rootNode->right);//遍历右子树
     }
 }

 void TreeType::InorderTraverse(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         InorderTraverse(rootNode->left); //遍历左子树
         std::cout << rootNode->info << " ";//遍历根结点
         InorderTraverse(rootNode->right); //遍历右子树
     }
 }

 void TreeType::PostorderTraverse(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         PostorderTraverse(rootNode->left); //遍历左子树
         PostorderTraverse(rootNode->right); //遍历右子树
         std::cout << rootNode->info << " ";//遍历根结点
     }
 }

 

----------------------------------------------main.cpp------------------------------------------

main.cpp 

         std::cout << "PreorderTraverse: " << endl;
         binarySearchTree.PreorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverse: " << endl;
         binarySearchTree.InorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverse: " << endl;
         binarySearchTree.PostorderTraverse(binarySearchTree.root);
         std::cout << endl;
         std::cout << endl;

 

输出结果如下:



64.3 向二叉查找树中插入若干个结点


这个方式和“64.1 建立二叉查找树”基本完全相同,此处不赘述,贴出代码如下:

----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        void InsertItems(ItemType *itemArray, int itemNum);


----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

void TreeType::InsertItems(ItemType *itemArray, int itemNum) {
     for(int i=0; i<itemNum; i++) {
         TreeNode *newnode = new TreeNode;
         newnode->info = itemArray[i];
         newnode->left = NULL;
         newnode->right = NULL;
         if(root == NULL) {
             root = newnode;
             std::cout << itemArray[i] << " will be the root" << endl;
         }
         else {
             TreeNode *parent;
             TreeNode *temp = root;
             while(temp != NULL) {
                 parent = temp;
                 if((temp->info) > itemArray[i]) {
                     temp = temp->left;
                 }
                 else if((temp->info) == itemArray[i]) {
                    break;
                 }
                 else {
                     temp = temp->right;
                 }
             }

             if((parent->info) > itemArray[i]) {
                 parent->left = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s left child" << endl;
             }
             else if((parent->info) == itemArray[i]) {
                 std::cout << "there has been a " << itemArray[i] << " in the tree" << endl;
             }
             else {
                 parent->right = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s right child" << endl;
             }
         }
    }
}

----------------------------------------------main.cpp------------------------------------------

main.cpp

/*先插入4个数据,其中的“28”已经在树中,所以实际插入的是3个数据:403242。然后将整棵树按照三种方式分别进行遍历*/

         ItemType insertItems[4] = {40, 32, 42, 28};
         std::cout << "InsertItems: ";
         for (int i=0; i<4; i++) {
            std::cout << insertItems[i] << " ";
         }
         std::cout << endl;
         binarySearchTree.InsertItems(insertItems, 4);
         std::cout << endl;

         std::cout << "PreorderTraverse: " << endl;
         binarySearchTree.PreorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverse: " << endl;
         binarySearchTree.InorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverse: " << endl;
         binarySearchTree.PostorderTraverse(binarySearchTree.root);
         std::cout << endl;

                                                                            

输出结果如下:


对应二叉查找树的示意图如下:


64.4 查找二叉查找树中某个结点


我们采用递归的方法来完成某个结点的查找。

算法:

先查找根结点,若根结点是要找的结点,直接输出根结点内容;

若根结点不是要找的结点,按照递归的方法分别查找左子树和右子树;

 

C++代码如下:

 

----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        bool FindItem(TreeNode *rootNode, ItemType item);


----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

bool TreeType::FindItem(TreeNode *rootNode, ItemType item) {
    if (rootNode == NULL) {
        return  false;
    }
    else {
        if ((rootNode->info) == item) {
            std::cout << "found." << endl;
            if ((rootNode->left) != NULL) {
                std::cout << "its left child is " << rootNode->left->info << " ." << endl;
            }
            if ((rootNode->right) != NULL) {
                std::cout << "its right child is " << rootNode->right->info << " ." << endl;
            }
            return true;
        }
        else {
            if (FindItem(rootNode->left, item)) {
                return true;
            }
            if (FindItem(rootNode->right, item)) {
                return true;
            }
            return false;
        }
    }
}

ItemType TreeType::MinValue(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         if ((rootNode->left) != NULL) {
            MinValue(rootNode->left);
         }
         else {
            return rootNode->info;
         }
     }
}

 

----------------------------------------------main.cpp------------------------------------------

main.cpp

         std::cout << endl;
         ItemType item = 35;
         bool found;
         std::cout << "FindItem: " << item << endl;
         found = binarySearchTree.FindItem(binarySearchTree.root, item);
         std::cout << "found: " << found << endl;

 

输出结果如下:

64.5 查找二叉查找树中的最大值和最小值


我们知道,二叉查找树是有序序列,而且左子树中所有的值都比根结点的值小,右子树中所有的值都比根结点的值大。所以,最大值是最右边的那个值,最小值是最左边的那个值。进一步分析:最大值为中序遍历的最后一个值,最小值为中序遍历大的第一个值。

 

C++代码如下:

 

----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        ItemType MinValue(TreeNode *rootNode);
        ItemType MaxValue(TreeNode *rootNode);


----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

ItemType TreeType::MaxValue(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         if ((rootNode->right) != NULL) {
            MaxValue(rootNode->right);
         }
         else {
            return rootNode->info;
         }
     }
}

----------------------------------------------main.cpp------------------------------------------

main.cpp

         std::cout << endl;
         std::cout << "MinValue: " << endl;
         ItemType minItem = binarySearchTree.MinValue(binarySearchTree.root);
         std::cout << "minItem: " << minItem << endl;

         std::cout << endl;
         std::cout << "MaxValue: " << endl;
         ItemType maxItem = binarySearchTree.MaxValue(binarySearchTree.root);
         std::cout << "maxItem: " << maxItem << endl;

 

输出结果如下:

64.6 求二叉查找树的总的结点数


我们采用递归的方法来求二叉查找树的总的结点数。

算法:

总的结点数=左子树的结点数+右子树的结点数+1(根结点)

 

C++代码如下:

 

----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        int NodesNum(TreeNode *rootNode);

----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

int TreeType::NodesNum(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
        return (NodesNum(rootNode->left) + NodesNum(rootNode->right) + 1);
     }
     else {
        return 0;
     }
}

----------------------------------------------main.cpp------------------------------------------

main.cpp

         std::cout << endl;
         std::cout << "NodesNum: " << endl;
         int num = binarySearchTree.NodesNum(binarySearchTree.root);
         std::cout << "NodesNum: " << num << endl;

输出结果如下:

64.7 求二叉查找树中叶子结点的个数及遍历叶子结点


叶子结点,即没有左孩子和右孩子的结点。如上二叉查找树的叶子结点如下图蓝色圈示意:


 

C++代码实现如下:

 

----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        void LeavesNum(TreeNode *rootNode, int &num);
        void PreorderTraverseLeaves(TreeNode *rootNode);
        void InorderTraverseLeaves(TreeNode *rootNode);
        void PostorderTraverseLeaves(TreeNode *rootNode);

 

----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

void TreeType::LeavesNum(TreeNode *rootNode, int &num) {
     if(rootNode!=NULL)
     {
        if (((rootNode->left) == NULL) && ((rootNode->right) == NULL)) {
            num ++;
        }
        else {
            LeavesNum(rootNode->left, num);
            LeavesNum(rootNode->right, num);
        }
     }
}


void TreeType::PreorderTraverseLeaves(TreeNode *rootNode) {
    if(rootNode!=NULL) {
        if ((rootNode->left == NULL) && (rootNode->right == NULL)) {
            std::cout << rootNode->info << " ";
        }
        PreorderTraverseLeaves(rootNode->left);
        PreorderTraverseLeaves(rootNode->right);
    }
}

void TreeType::InorderTraverseLeaves(TreeNode *rootNode) {
    if(rootNode!=NULL) {
        InorderTraverseLeaves(rootNode->left);
        if ((rootNode->left == NULL) && (rootNode->right == NULL)) {
            std::cout << rootNode->info << " ";
        }
        InorderTraverseLeaves(rootNode->right);
    }
}

void TreeType::PostorderTraverseLeaves(TreeNode *rootNode) {
    if(rootNode!=NULL)
    {
        PostorderTraverseLeaves(rootNode->left);
        PostorderTraverseLeaves(rootNode->right);
        if ((rootNode->left == NULL) && (rootNode->right == NULL)) {
            std::cout << rootNode->info << " ";
        }
    }
}

 

----------------------------------------------main.cpp------------------------------------------

main.cpp

         std::cout << endl;
         std::cout << "LeavesNum: " << endl;
         int lnum = 0;
         binarySearchTree.LeavesNum(binarySearchTree.root, lnum);
         std::cout << "LeavesNum: " << lnum << endl;

         std::cout << "PreorderTraverseLeaves: " << endl;
         binarySearchTree.PreorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverseLeaves: " << endl;
         binarySearchTree.InorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverseLeaves: " << endl;
         binarySearchTree.PostorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

 

输出结果如下:

 

64.8 删除二叉查找树中某个结点


删除某个结点,步骤如下:

1,在二叉查找树中找到该结点;

2,将该结点的父结点对应的左孩子或者右孩子的指针设为空;

3,删除以该结点为根结点的子树;

 

比如,若删除结点“45”,则是下图中蓝色圈内的4个结点。


 

C++代码如下:

 

----------------------------------------------TreeType.h------------------------------------------

TreeType.h

        bool DeleteItem(TreeNode *rootNode, ItemType item);

 

----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

void DeleteTree(TreeNode *rootNode) {
    if (rootNode == NULL) {
    }
    else {
        TreeNode *temp_left = rootNode->left;
        TreeNode *temp_right = rootNode->right;
        delete rootNode;
        if (temp_left != NULL) {
            DeleteTree(temp_left);
        }
        if (temp_right != NULL) {
            DeleteTree(temp_right);
        }
    }
 }

bool TreeType::DeleteItem(TreeNode *rootNode, ItemType item) {
    if (rootNode == NULL) {
        return  false;
    }
    else {
        if (rootNode->left != NULL) {
            if (rootNode->left->info == item) {
                DeleteTree(rootNode->left);
                rootNode->left = NULL;
                return true;
            }
        }
        if (rootNode->right != NULL) {
            if (rootNode->right->info == item) {
                DeleteTree(rootNode->right);
                rootNode->right = NULL;
                return true;
            }
        }
        if (DeleteItem(rootNode->left, item)) {
            return true;
        }
        if (DeleteItem(rootNode->right, item)) {
            return true;
        }
        else {
            return false;
        }
    }
 }


----------------------------------------------main.cpp------------------------------------------

main.cpp

/*先删除结点“45”(即以该结点为根结点的子树)。然后在遍历完成删除动作后剩余的树,同时计算剩余结点数,和剩余叶子结点数,再遍历叶子结点*/

         std::cout << endl;
         item = 45;
         std::cout << "DeleteItem: " << item << endl;
         bool deleted = binarySearchTree.DeleteItem(binarySearchTree.root, item);
         std::cout << "deleted: " << deleted << endl;
         std::cout << endl;

         std::cout << "PreorderTraverse: " << endl;
         binarySearchTree.PreorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverse: " << endl;
         binarySearchTree.InorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverse: " << endl;
         binarySearchTree.PostorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << endl;
         std::cout << "NodesNum: " << endl;
         num = binarySearchTree.NodesNum(binarySearchTree.root);
         std::cout << "NodesNum: " << num << endl;

         std::cout << endl;
         std::cout << "LeavesNum: " << endl;
         lnum = 0;
         binarySearchTree.LeavesNum(binarySearchTree.root, lnum);
         std::cout << "LeavesNum: " << lnum << endl;

         std::cout << "PreorderTraverseLeaves: " << endl;
         binarySearchTree.PreorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverseLeaves: " << endl;
         binarySearchTree.InorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverseLeaves: " << endl;
         binarySearchTree.PostorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

 

输出结果如下:


64.9 C++代码汇总


----------------------------------------------TreeType.h------------------------------------------

TreeType.h

#ifndef TREETYPE_H
#define TREETYPE_H

#include <iostream>

using namespace std;

typedef int ItemType;

struct TreeNode
{
    ItemType info;
    TreeNode* left;
    TreeNode* right;
};

class TreeType {// binary search tree.
    public:
        TreeType() {
            root = NULL;
        }
        void CreateTree(ItemType *itemArray, int itemNum);
        void PreorderTraverse(TreeNode *rootNode);
        void InorderTraverse(TreeNode *rootNode);
        void PostorderTraverse(TreeNode *rootNode);
        void InsertItems(ItemType *itemArray, int itemNum);
        bool FindItem(TreeNode *rootNode, ItemType item);
        ItemType MinValue(TreeNode *rootNode);
        ItemType MaxValue(TreeNode *rootNode);
        int NodesNum(TreeNode *rootNode);
        void LeavesNum(TreeNode *rootNode, int &num);
        void PreorderTraverseLeaves(TreeNode *rootNode);
        void InorderTraverseLeaves(TreeNode *rootNode);
        void PostorderTraverseLeaves(TreeNode *rootNode);
        bool DeleteItem(TreeNode *rootNode, ItemType item);

        TreeNode *root;
};


#endif // TREETYPE_H

----------------------------------------------TreeType.cpp------------------------------------------

TreeType.cpp

#include "TreeType.h"

void TreeType::CreateTree(ItemType *itemArray, int itemNum) {
     for(int i=0; i<itemNum; i++) {
         TreeNode *newnode = new TreeNode;
         newnode->info = itemArray[i];
         newnode->left = NULL;
         newnode->right = NULL;
         if(root == NULL) {
             root = newnode;
             std::cout << itemArray[i] << " will be the root" << endl;
         }
         else {
             TreeNode *parent;
             TreeNode *temp = root;
             while(temp != NULL) {
                 parent = temp;
                 if((temp->info) > itemArray[i]) {
                     temp = temp->left;
                 }
                 else {
                     temp = temp->right;
                 }
             }

             if((parent->info) > itemArray[i]) {
                 parent->left = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s left child" << endl;
             }
             else {
                 parent->right = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s right child" << endl;
             }
         }
    }
}

 void TreeType::PreorderTraverse(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         std::cout << rootNode->info << " ";
         PreorderTraverse(rootNode->left);
         PreorderTraverse(rootNode->right);
     }
 }

 void TreeType::InorderTraverse(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         InorderTraverse(rootNode->left);
         std::cout << rootNode->info << " ";
         InorderTraverse(rootNode->right);
     }
 }

 void TreeType::PostorderTraverse(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         PostorderTraverse(rootNode->left);
         PostorderTraverse(rootNode->right);
         std::cout << rootNode->info << " ";
     }
 }

void TreeType::InsertItems(ItemType *itemArray, int itemNum) {
     for(int i=0; i<itemNum; i++) {
         TreeNode *newnode = new TreeNode;
         newnode->info = itemArray[i];
         newnode->left = NULL;
         newnode->right = NULL;
         if(root == NULL) {
             root = newnode;
             std::cout << itemArray[i] << " will be the root" << endl;
         }
         else {
             TreeNode *parent;
             TreeNode *temp = root;
             while(temp != NULL) {
                 parent = temp;
                 if((temp->info) > itemArray[i]) {
                     temp = temp->left;
                 }
                 else if((temp->info) == itemArray[i]) {
                    break;
                 }
                 else {
                     temp = temp->right;
                 }
             }

             if((parent->info) > itemArray[i]) {
                 parent->left = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s left child" << endl;
             }
             else if((parent->info) == itemArray[i]) {
                 std::cout << "there has been a " << itemArray[i] << " in the tree" << endl;
             }
             else {
                 parent->right = newnode;
                 std::cout << itemArray[i] << " will be " << parent->info << "'s right child" << endl;
             }
         }
    }
}

bool TreeType::FindItem(TreeNode *rootNode, ItemType item) {
    if (rootNode == NULL) {
        return  false;
    }
    else {
        if ((rootNode->info) == item) {
            std::cout << "found." << endl;
            if ((rootNode->left) != NULL) {
                std::cout << "its left child is " << rootNode->left->info << " ." << endl;
            }
            if ((rootNode->right) != NULL) {
                std::cout << "its right child is " << rootNode->right->info << " ." << endl;
            }
            return true;
        }
        else {
            if (FindItem(rootNode->left, item)) {
                return true;
            }
            if (FindItem(rootNode->right, item)) {
                return true;
            }
            return false;
        }
    }
}

ItemType TreeType::MinValue(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         if ((rootNode->left) != NULL) {
            MinValue(rootNode->left);
         }
         else {
            return rootNode->info;
         }
     }
}

ItemType TreeType::MaxValue(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
         if ((rootNode->right) != NULL) {
            MaxValue(rootNode->right);
         }
         else {
            return rootNode->info;
         }
     }
}

int TreeType::NodesNum(TreeNode *rootNode) {
     if(rootNode!=NULL)
     {
        return (NodesNum(rootNode->left) + NodesNum(rootNode->right) + 1);
     }
     else {
        return 0;
     }
}

void TreeType::LeavesNum(TreeNode *rootNode, int &num) {
     if(rootNode!=NULL)
     {
        if (((rootNode->left) == NULL) && ((rootNode->right) == NULL)) {
            num ++;
        }
        else {
            LeavesNum(rootNode->left, num);
            LeavesNum(rootNode->right, num);
        }
     }
}


void TreeType::PreorderTraverseLeaves(TreeNode *rootNode) {
    if(rootNode!=NULL) {
        if ((rootNode->left == NULL) && (rootNode->right == NULL)) {
            std::cout << rootNode->info << " ";
        }
        PreorderTraverseLeaves(rootNode->left);
        PreorderTraverseLeaves(rootNode->right);
    }
}

void TreeType::InorderTraverseLeaves(TreeNode *rootNode) {
    if(rootNode!=NULL) {
        InorderTraverseLeaves(rootNode->left);
        if ((rootNode->left == NULL) && (rootNode->right == NULL)) {
            std::cout << rootNode->info << " ";
        }
        InorderTraverseLeaves(rootNode->right);
    }
}

void TreeType::PostorderTraverseLeaves(TreeNode *rootNode) {
    if(rootNode!=NULL)
    {
        PostorderTraverseLeaves(rootNode->left);
        PostorderTraverseLeaves(rootNode->right);
        if ((rootNode->left == NULL) && (rootNode->right == NULL)) {
            std::cout << rootNode->info << " ";
        }
    }
}

void DeleteTree(TreeNode *rootNode) {
    if (rootNode == NULL) {
    }
    else {
        TreeNode *temp_left = rootNode->left;
        TreeNode *temp_right = rootNode->right;
        delete rootNode;
        if (temp_left != NULL) {
            DeleteTree(temp_left);
        }
        if (temp_right != NULL) {
            DeleteTree(temp_right);
        }
    }
 }

 bool TreeType::DeleteItem(TreeNode *rootNode, ItemType item) {
    if (rootNode == NULL) {
        return  false;
    }
    else {
        if (rootNode->left != NULL) {
            if (rootNode->left->info == item) {
                DeleteTree(rootNode->left);
                rootNode->left = NULL;
                return true;
            }
        }
        if (rootNode->right != NULL) {
            if (rootNode->right->info == item) {
                DeleteTree(rootNode->right);
                rootNode->right = NULL;
                return true;
            }
        }
        if (DeleteItem(rootNode->left, item)) {
            return true;
        }
        if (DeleteItem(rootNode->right, item)) {
            return true;
        }
        else {
            return false;
        }
    }
 }

 

----------------------------------------------main.cpp------------------------------------------

main.cpp

    #include <iostream>
    #include <fstream>
    #include <limits>
    #include <stdlib.h>

    #include <TreeType.h>

    using namespace std;

    int main()
    {
         TreeType binarySearchTree;
         ItemType infoArray[15] = {20, 12, 2, 14, 15, 35, 6, 45, 25, 23, 1, 24, 16, 57, 28};
         std::cout << "CreateTree: " << endl;
         binarySearchTree.CreateTree(infoArray, 15);
         std::cout << endl;

         std::cout << "PreorderTraverse: " << endl;
         binarySearchTree.PreorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverse: " << endl;
         binarySearchTree.InorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverse: " << endl;
         binarySearchTree.PostorderTraverse(binarySearchTree.root);
         std::cout << endl;
         std::cout << endl;

         ItemType insertItems[4] = {40, 32, 42, 28};
         std::cout << "InsertItems: ";
         for (int i=0; i<4; i++) {
            std::cout << insertItems[i] << " ";
         }
         std::cout << endl;
         binarySearchTree.InsertItems(insertItems, 4);
         std::cout << endl;

         std::cout << "PreorderTraverse: " << endl;
         binarySearchTree.PreorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverse: " << endl;
         binarySearchTree.InorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverse: " << endl;
         binarySearchTree.PostorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << endl;
         ItemType item = 35;
         bool found;
         std::cout << "FindItem: " << item << endl;
         found = binarySearchTree.FindItem(binarySearchTree.root, item);
         std::cout << "found: " << found << endl;

         std::cout << endl;
         std::cout << "MinValue: " << endl;
         ItemType minItem = binarySearchTree.MinValue(binarySearchTree.root);
         std::cout << "minItem: " << minItem << endl;

         std::cout << endl;
         std::cout << "MaxValue: " << endl;
         ItemType maxItem = binarySearchTree.MaxValue(binarySearchTree.root);
         std::cout << "maxItem: " << maxItem << endl;

         std::cout << endl;
         std::cout << "NodesNum: " << endl;
         int num = binarySearchTree.NodesNum(binarySearchTree.root);
         std::cout << "NodesNum: " << num << endl;

         std::cout << endl;
         std::cout << "LeavesNum: " << endl;
         int lnum = 0;
         binarySearchTree.LeavesNum(binarySearchTree.root, lnum);
         std::cout << "LeavesNum: " << lnum << endl;

         std::cout << "PreorderTraverseLeaves: " << endl;
         binarySearchTree.PreorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverseLeaves: " << endl;
         binarySearchTree.InorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverseLeaves: " << endl;
         binarySearchTree.PostorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << endl;
         item = 45;
         std::cout << "DeleteItem: " << item << endl;
         bool deleted = binarySearchTree.DeleteItem(binarySearchTree.root, item);
         std::cout << "deleted: " << deleted << endl;
         std::cout << endl;

         std::cout << "PreorderTraverse: " << endl;
         binarySearchTree.PreorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverse: " << endl;
         binarySearchTree.InorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverse: " << endl;
         binarySearchTree.PostorderTraverse(binarySearchTree.root);
         std::cout << endl;

         std::cout << endl;
         std::cout << "NodesNum: " << endl;
         num = binarySearchTree.NodesNum(binarySearchTree.root);
         std::cout << "NodesNum: " << num << endl;

         std::cout << endl;
         std::cout << "LeavesNum: " << endl;
         lnum = 0;
         binarySearchTree.LeavesNum(binarySearchTree.root, lnum);
         std::cout << "LeavesNum: " << lnum << endl;

         std::cout << "PreorderTraverseLeaves: " << endl;
         binarySearchTree.PreorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "InorderTraverseLeaves: " << endl;
         binarySearchTree.InorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;

         std::cout << "PostorderTraverseLeaves: " << endl;
         binarySearchTree.PostorderTraverseLeaves(binarySearchTree.root);
         std::cout << endl;
    }

 

输出结果如下:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值