二叉排序树实现(C++封装)

设计一个类,根结点只可读取,具备构造二叉树、插入结点、删除结点、查找、 查找最大值、查找最小值、查找指定结点的前驱和后继等功能接口。

二叉排序树概念

它或者是一棵空树;或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树。

二叉排序树的各种操作

插入新节点
这是一个递归操作,递归设计时要找到最源头,才能得到最简设计。一种设计是判断叶子节点,把新节点作为叶子节点的孩子插入;一种是永远当作根进行插入,插入节点永远是当前子树的根!看代码:


//root为二级指针的原因是,如果树为空,需要将根修改反馈回来
bool BinaryTree::InsertNode(pNode * cuRoot, int data, pNode self)
{  //递归设计时找到最源头,才能得到最简设计
    if (*cuRoot == nullptr){
        pNode node = new Node;
        if (node == nullptr)
            return false;
        node->data = data;
        node->lChild = node->rChild = node->parent = nullptr;
        (*cuRoot) = node;
        node->parent = self;
        return true;
    }
    if (data > (*cuRoot)->data)
        InsertNode(&(*cuRoot)->rChild, data, *cuRoot);
    else
        InsertNode(&(*cuRoot)->lChild, data, *cuRoot);
    return true;
}

构造函数
一共两个重载函数:一个无参,一个接受数组利用插入函数直接构造二叉排序树。

BinaryTree::BinaryTree(int * datum, int len)
{
    root = nullptr;
    for (int i = 0; i < len; i++)
        InsertNode(&root, datum[i], root);
}

BinaryTree::BinaryTree()
{
    root = nullptr;
}

查找函数
这也是一个递归操作,为了对外隐藏root(根节点),因此编写了一个私有函数,进行真正的查找操作。

//真正的查找函数
BinaryTree::pNode BinaryTree::_searchKey(pNode root, int key){
    if (root == nullptr)
        return nullptr;
    if (root->data == key)    //找到了
        return root;
    else if (root->data > key)//值偏小,到左子树找
        return _searchKey(root->lChild, key);
    else                      //值偏大,到右子树找
        return _searchKey(root->rChild, key);
}
//对外接口
BinaryTree::pNode BinaryTree::SearchKey(int key){
    return _searchKey(root, key);
}

找前驱节点
要么为左子树中最大者,要么一直追溯其父节点链,第一个是其父节点的右孩子的父节点,即为所求。

BinaryTree::pNode BinaryTree::SearchPredecessor(pNode node){
    if (node == nullptr)
        return nullptr;
    else if (node->lChild != nullptr)
        return SearchMaxNode(node->lChild);
    else
    {
        if (node->parent == nullptr)
            return nullptr;
        while (node)
        {
            if (node->parent->rChild == node)
                break;
            node = node->parent;
        }
        return node->parent;
    }
}

找后继节点
与找前驱节点基本相似。 要么为右子树中最小者,要么一直追溯其父节点链,第一个是其父节点的左孩子的父节点,即为所求。

BinaryTree::pNode BinaryTree::SearchSuccessor(pNode node){
    if (node == nullptr)
        return nullptr;
    else if (node->rChild != nullptr)
        return SearchMinNode(node->rChild);
    else
    {
        if (node->parent == nullptr)
            return nullptr;
        while (node)
        {
            if (node->parent->lChild == node)
                break;
            node = node->parent;
        }
        return node->parent;
    }
}

找最小值

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b69980c2a9790027ece03b3e9a62da6d.html