dictionary.h
//抽象类词典
//字典数据结构的抽象数据类型规范
//所有方法都是纯虚函数
//K是键类型,E是值类型
#ifndef DICTIONARY_H
#define DICTIONARY_H
using namespace std;
template<class K, class E>
class dictionary
{
public:
virtual ~dictionary() {}
virtual bool empty() const = 0;
// 返回 true,当且仅当字典为空
virtual int size() const = 0;
// 返回字典中数对的数目
virtual pair<const K, E>* find(const K&) const = 0;
//返回匹配数对的指针
virtual void erase(const K&) = 0;
// 删除匹配的数对
virtual void insert(const pair<const K, E>&) = 0;
// 往字典中插入一个数对
};
#endif // !DICTIONARY_H
bsTree.h
//抽象类bsTree
//二叉搜索树的抽象数据类型规范
//所有方法都是纯虚函数
//K是键类型,E是值类型
#ifndef BSTREE_H
#define BSTREE_H
#include "dictionary.h"
template<typename K, typename E>
class bsTree : public dictionary<K, E>
{
public:
virtual void ascend() = 0;
// 按关键字的升序输出
};
#endif // !BSTREE_H
indexedBSTree.h
#ifndef INDEXEDBSTREE_H
#define INDEXEDBSTREE_H
#include "bsTree.h"
template<typename K, typename E>
class indexedBSTree : public bsTree<K, E>
{
public:
virtual pair<const K, E>* get(int) const = 0;
// 根据给定的索引,返回其数对的指针
virtual void delete(int) = 0;
// 根据给定的索引,删除其数对
};
#endif // !INDEXEDBSTREE_H
binarySearchTree.h
//二叉搜索树的链接二叉树实现
//实现所有dictionary和bsTree方法
#ifndef BINARYSEARCHTREE_H
#define BINARYSEARCHTREE_H
#include "bsTree.h"
#include "linkedBinaryTree.h"
#include "myExceptions.h"
using namespace std;
template<class K, class E>
class binarySearchTree : public bsTree<K,E>,
public linkedBinaryTree<pair<const K, E> >
{
public:
// 字典法
bool empty() const {return treeSize == 0;}
int size() const {return treeSize;}
pair<const K, E>* find(const K& theKey) const;
void insert(const pair<const K, E>& thePair);
void erase(const K& theKey);
// B树的附加方法
void ascend() {inOrderOutput();}
};
template<typename K, typename E>
pair<const K, E>* binarySearchTree<K, E>::find(const K& theKey) const
{// 返回值是匹配数对的指针
// 如果没有匹配的数对,返回值为 NULL
// p 从根节点开始搜索,寻找关键字等于 theKey 的一个元素
binarySearchTree<pair<const K, E>> * p = root;
while (p != nullptr)
// 检查元素
if (theKey < p->element.first)
p = p->leftChild;
else
if (theKey > p->element.first)
p = p->rightChild;
else // 找到匹配的元素
return &p->element;
// 无匹配数对
return nullptr;
}
template<class K, class E>
void binarySearchTree<K, E>::insert(const pair<const K, E>& thePair)
{// 输入 thePair。如果存在与其关键字相同的数对,则覆盖
// 寻找插入位置
binaryTreeNode<pair<const K, E>> *p = root,
*pp = nullptr;
while (p != nullptr)
{// 检查元素 p->element
pp = p;
// p 移到它的一个孩子节点
if (thePair.first < p->element.first)
p = p->leftChild;
else
if (thePair.first > p->element.first)
p = p->rightChild
else
{// 覆盖旧值
p->element.second = thePair.second;
return;
}
}
// 为 thePair 建立一个节点,然后与 pp 链接
binarySearchTree<pair<const K, E>> * newNode = new binarySearchTree<pair<const K, E>>(thePair);
if (root != nullpre) // 树不空
if (thePair.first < pp->element.first)
pp->leftChild = newNode;
else
pp->rightChild = newNode;
else
root = newNode; // 插入空树
treeSize++;
}
template<typename K, typename E>
void binarySearchTree<K, E>::erase(const K& theKey)
{// 删除其关键字等于 theKey 的数对
// 查找关键字为 theKey 的节点
binarySearchTree<pair<const K, E>> *p = root,
*pp = nullptr;
while (p != nullptr && p->element.first != theKey)
{// p 移到它的一个孩子节点
pp = p;
if (theKey < p->element.first)
p = p->leftChild;
else
p = p->rightChild;
}
if (p == nullptr)
return; // 不存在于关键字 theKey 匹配的数对
// 重新组织树结构
// 当 p 有两个孩子时的处理
if (p->leftChild != nullptr && p->rightChild)
{// 两个孩子
// 转化为空或只有一个孩子
// 在 p 的左子树中寻找最大元素
binaryTreeNode<pair<const K, E>> *s = p->leftChild,
*ps = p; // s 的双亲
while (s->rightChild != nullptr)
{// 移到最大的元素
ps = s;
s = s->rightChild;
}
// 将最大元素 s 移到 p,但不是简单的移动
// p->element = s->element,因为 key 是常量
binaryTreeNode<pair<const K, E>> *q = new binaryTreeNode<pair<const K, e>>(s->element, s->leftChildm, s->rightChild);
if (pp == nullptr)
root = q;
if (pp == nullptr)
root = q;
else if (p == pp->leftChild)
pp->leftChild = q;
else
pp->rightChild = q;
if (ps == p)
pp = q;
else
pp = ps;
delete p;
p = s;
}
// p 最多有一个孩子
// 把孩子指针存放在 c
binaryTreeNode<pair<const K, E>> *c;
if (p->leftChild != nullptr)
c = p->leftChild;
else
c = p->rightChild;
// 删除 p
if (p == root)
root = c;
else
{// p 是 pp 的左孩子还是右孩子?
if (p == pp->leftChild)
pp->leftChild = c;
else
pp->rightChild = c;
}
treeSize--;
delete p;
}
// 重载 << 对
template <class K, class E>
ostream& operator<<(ostream& out, const pair<K, E>& x)
{out << x.first << ' ' << x.second; return out;}
#endif