数据结构、算法与应用 搜索树

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值