异常类 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; }