数据结构C++(13)搜索树——链式实现(binarySearchTree)

异常类 myExceptions 同 数据结构C++(1)线性表——数组实现(arrayList) 。

抽象基类 queue ,类vectorQueue 的定义同 数据结构C++(6)队列——vector实现(vectorQueue)

抽象类 dictionary 的定义同 数据结构C++(8)字典——链表实现(linkDictionary)

抽象基类 binaryTree ,结构 binaryTreeNode, 类 linkBinaryTree 的定义同 数据结构C++(10)二叉树——链表实现(linkBinaryTree)

搜索树抽象基类 search 定义在 search.h 中:

1 #pragma once
2 #include "dictionary.h"
3 
4 template<typename K, typename V>
5 class search : public dictionary<K, V>
6 {
7 public:
8     virtual void ascend() = 0;        //按关键字升序输出
9 };

类 binarySearchTree 的定义在 binarySearchTree.h 中:

#pragma once
#include <iostream>
#include "search.h"
#include "linkBinaryTree.h"

template<typename K, typename V>
class binarySearchTree : public linkBinaryTree<std::pair<const K, V> >, public search<K, V>
{
public:
    bool empty() const { return this->treeSize == 0; }
    int size() const { return this->treeSize; }
    std::pair<const K, V>* find(const K &theKey) const;    //查找键为key的数对
    void erase(const K &theKey);
    void insert(const std::pair<const K, V>& thePair);

    void ascend()
    {
        std::cout << "this->Root = " << this->Root << std::endl;
        this->outputInOrder(std::cout); }
};

template<typename K, typename V>
std::pair<const K, V>* binarySearchTree<K, V>::find(const K &theKey) const    //查找键为key的数对
{
    std::pair<const K, V> *Find = nullptr;
    binaryTreeNode<std::pair<const K, V> > *Tmp = this->Root;
    while (nullptr != Tmp)
    {
        if (theKey < Tmp->element.first)
            Tmp = Tmp->leftChild;
        else if (theKey > Tmp->element.first)
            Tmp = Tmp->leftChild;
        else
        {
            Find = &Tmp->element;
            break;
        }
    }
    return Find;
}

template<typename K, typename V>
void binarySearchTree<K, V>::erase(const K &theKey)
{
    binaryTreeNode<std::pair<const K, V> > *Tmp = nullptr, *Del = this->Root;
    while ((Del != nullptr) && (Del->element.first != theKey))
    {
        Tmp = Del;
        if (theKey < Del->element.first)
            Del = Del->leftChild;
        else
            Del = Del->rightChild;
    }
    if (nullptr == Del)
        return;
    
    binaryTreeNode<std::pair<const K, V> > *New = nullptr, *pNew = nullptr;
    if (Del->leftChild != nullptr)    //左子树不为空
    {
        //将该结点左子树的最大结点移动到此
        binaryTreeNode<std::pair<const K, V> > *leftMax = Del->leftChild, *pLeftMax = Del;
        while (nullptr != leftMax->rightChild)
        {
            pLeftMax = leftMax;
            leftMax = leftMax->rightChild;
        }                    
        if (leftMax != Del->leftChild)
            leftMax->leftChild = Del->leftChild;
        if (pLeftMax != Del)
            pLeftMax->rightChild = nullptr;
        if (leftMax != Del->rightChild)
            leftMax->rightChild = Del->rightChild;
        New = leftMax;
        pNew = pLeftMax;
    }    
    else                            //左子树为空
    {
        binaryTreeNode<std::pair<const K, V> > *rightMin = Del->rightChild, *pRightMin = Del;
        while (nullptr != rightMin->leftChild)
        {
            pRightMin = rightMin;
            rightMin = rightMin->leftChild;
        }
        if (rightMin != Del->rightChild)
            rightMin->rightChild = Del->rightChild;
        if (pRightMin != Del)
            pRightMin->leftChild = nullptr;
        if (rightMin != Del->leftChild)
            rightMin->leftChild = Del->leftChild;
        New = rightMin;
        pNew = pRightMin;
    }
    if (Del == this->Root)        //要删除的结点是根结点
        this->Root = New;
    else
    {
        if ((Del->leftChild != nullptr) || (Del->rightChild != nullptr))    //要删除的不是叶子结点
        {
            if (Tmp->element.first > theKey)
                Tmp->leftChild = New;
            else
                Tmp->rightChild = New;
        }
    }
    delete Del;
}

template<typename K, typename V>
void binarySearchTree<K, V>::insert(const std::pair<const K, V>& thePair)
{
    binaryTreeNode<std::pair<const K, V> > *Tmp = this->Root, *pTmp = nullptr;
    while ((nullptr != Tmp) && (Tmp->element.first != thePair.first))
    {
        pTmp = Tmp;
        if (Tmp->element.first > thePair.first)
            Tmp = Tmp->leftChild;
        else
            Tmp = Tmp->rightChild;
    }
    if (this->Root == nullptr)                                //根结点为空
        this->Root = new binaryTreeNode<std::pair<const K, V> >(thePair); 
    else
    {
        if (Tmp == nullptr)                                //不存在,创建
        {
            binaryTreeNode<std::pair<const K, V> > *New = new binaryTreeNode<std::pair<const K, V> >(thePair);
            if (pTmp->element.first > thePair.first)
                pTmp->leftChild = New;
            else
                pTmp->rightChild = New;
        }
        else if (Tmp->element.first == thePair.first)        //该数对存在,替换值
            Tmp->element.second = thePair.second;
    }
}

template<typename K, typename V>
std::ostream &operator<<(std::ostream &out, std::pair<K, V> &Pair)
{
    out << Pair.first << " : " << Pair.second << "  ";
    return out;
}

关于 模板继承与类继承的一切区别:

模板继承与类继承的区别:
bool empty() const { return treeSize == 0; }
上面这条语句编译器是无法通过编译的。编译器报错treeSize不存在。
但是我们明明在基类Test中定义了,编译器却看不到它们,这是为什么呢?
这个问题在于,当编译器遭遇class template T定义式时,
并不知道它继承什么样的class。当然它继承的是linkBinaryTree<std::pair<K, V> >,
但其中std::pair<K, V>是template参数,binarySearchTree被具体化无法确切知道它是什么。
我们可以有三种方式解决这个问题:

(1)在变量或被调函数调用动作之前加上“this ->”。
bool empty() const { return this->treeSize == 0; }
(2)使用using声明式。
using linkBinaryTree<std::pair<K, V> >::treeSize;
bool empty() const { return treeSize == 0; }
(3)明确的指出变量或被调函数位于linkBinaryTree<std::pair<K, V> >内。
bool empty() const { return linkBinaryTree<std::pair<K, V> >::treeSize == 0; }

转载于:https://www.cnblogs.com/peformer/p/8082323.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值