《数据结构、算法与应用C++语言描述》-代码实现键值有序链表字典

字典

定义

字典(dictionary)是由一些形如(k,v)的数对所组成的集合,其中k是关键字,v是与关键字k对应的值(也可以说,v是值,它的关键字是 k)。任意两个数对,其关键字都不等。

多重字典:两个或更多的数对可以具有相同的关键字。

在一个多重字典中进行查找和删除操作时,需要消除歧义。就查找而言,有两种可能:
1)查找任何一个具备给定关键字的数对;

2)查找所有具备给定关键字的数对。就删除操作而言,我们要求给用户提供与给定关键字对应的所有数对,由用户选择删除哪些数对。此外,可以任意删除与给定关键字对应的一个数对或所有数对。

抽象数据类型

《数据结构、算法与应用C++语言描述》-代码实现键值有序链表字典_第1张图片

代码实现键值有序链表字典

main.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			main()函数,控制运行所有的测试函数
*/
#include "_23dictionaryChain.h"

int main()
{
    dictionaryChainTest();
}

_23dictionaryChain.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月22日09点17分
Last Version:			V1.0
Descriptions:			使用链表实现的字典的头文件---是有序的
*/
#pragma once
#ifndef _DICTIONARY_CHAIN_H_
#define _DICTIONARY_CHAIN_H_
#include 
#include "_23pairNode.h"
#include "_23dictionary.h"
using namespace std;
/*测试函数*/
void dictionaryChainTest();

template<class K, class E>
class dictionaryChain : public dictionary<K, E>
{
public:
    /*成员函数*/
    /*构造函数和析构函数*/
    dictionaryChain() { firstNode = nullptr; dSize = 0; }
    ~dictionaryChain();
    /*其他成员函数*/
    bool empty() const { return dSize == 0; }
    int size() const { return dSize; }
    pair<const K, E>* find(const K&) const;
    void erase(const K&);
    void insert(const pair<const K, E>&);

    /*友元函数*/
    /*输入字典*/
    istream& input(istream& in);
//    friend istream& operator>> (istream& in, dictionaryChain& m);
    /*输出字典*/
    ostream& output(ostream& out) const;
//    friend ostream& operator<< (ostream& out, const dictionaryChain& m);
protected:
    pairNode<K, E>* firstNode;  // pointer to first node in chain
    int dSize;                 // number of elements in dictionary
};

/*输入字典*/
template<class K, class E>
istream& dictionaryChain<K, E>::input(istream& in)
//istream& operator>>(istream& in, dictionaryChain& m)
{
    int numberOfElement = 0;
    cout << "Please enter the number of element:";
    while (!(in >> numberOfElement))
    {
        in.clear();//清空标志位
        while (in.get() != '\n')//删除无效的输入
            continue;
        cout << "Please enter the number of element:";
    }
    pair<K, E> element;
    for (int i = 0; i < numberOfElement; i++)
    {
        cout << "Please enter the element " << i + 1 << ":";
        while (!(in >> element.first >> element.second))
        {
            in.clear();//清空标志位
            while (in.get() != '\n')//删除无效的输入
                continue;
            cout << "Please enter the element " << i + 1 << ":";
        }
        insert(element);
    }
    return in;
}
template<class K, class E>
istream& operator>>(istream& in, dictionaryChain<K,E>& m){
    m.input(in);
    return in;
}
/*输出字典*/
template<class K, class E>
ostream& dictionaryChain<K, E>::output(ostream& out) const
//ostream& operator<<(ostream& out, const dictionaryChain& m)
{
    pairNode<K, E>* currentNode = firstNode;
    while (currentNode != nullptr)
    {
        out << "(" << currentNode->element.first << " ," << currentNode->element.second << ")" << " ";
        currentNode = currentNode->next;
    }
    cout << endl;
    return out;
}
template<class K, class E>
ostream& operator<<(ostream& out, const dictionaryChain<K,E>& m){
    m.output(out);
    return out;
}
/*析构函数*/
template<class K,class E>
dictionaryChain<K,E>::~dictionaryChain()
{
    pairNode<K, E>* nextNode;
    while (firstNode != nullptr)
    {
        nextNode = firstNode->next;
        delete firstNode;
        firstNode = nextNode;
    }
}
/*寻找关键字为key的数对并返回*/
template<class K, class E>
pair<const K, E>* dictionaryChain<K, E>::find(const K& key) const
{
    //返回匹配的数对的指针
    //如果不存在匹配的数对,则返回nullptr
    pairNode<K, E>* currentNode = firstNode;
    while (currentNode != nullptr && currentNode->element.first != key)
        currentNode = currentNode->next;
    if (currentNode != nullptr && currentNode->element.first == key)
        return &currentNode->element;
    return nullptr;//如果没找到就返回nullptr
}
/*删除关键字为key的数对*/
template<class K, class E>
void dictionaryChain<K, E>::erase(const K& key)
{
    //删除关键字为key的数对
    pairNode<K, E>* p = firstNode;//存储的是插入元素之后的位置
    pairNode<K, E>* tp = nullptr;//存储的是插入元素之前的位置
    //搜索关键字为key的数对
    while (p != nullptr && p->element.first < key)
    {
        tp = p;
        p = p->next;
    }
    //确定是否匹配
    if (p != nullptr && p->element.first == key)
        if (tp == nullptr) firstNode = p->next;//p是第一个节点
        else tp->next = p->next;
    delete p;
    dSize--;
}
/*往字典中插入data,覆盖已经存在的匹配的数对*/
template<class K,class E>
void dictionaryChain<K, E>::insert(const pair<const K, E>& data)
{
    pairNode<K, E>* p = firstNode;//存储的是插入元素之后的位置
    pairNode<K, E>* tp = nullptr;//存储的是插入元素之前的位置
    while (p != nullptr && p->element.first < data.first)
    {
        tp = p;
        p = p->next;
    }
    //检查是否有匹配的数对
    if (p != nullptr && p->element.first == data.first)
    {
        p->element.second = data.second;
        return;
    }
    //无匹配的数对,为thePair建立新节点
    pairNode<K, E>* newNode = new pairNode<K, E>(data, p);
    //在tp之后插入新节点
    if (tp == nullptr) firstNode = newNode;
    else tp->next = newNode;
    dSize++;
    return;
}

#endif

_23dictionaryChain.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月22日09点17分
Last Version:			V1.0
Descriptions:			使用链表实现的字典的cpp文件
*/
#include "_23dictionaryChain.h"
using namespace std;
void dictionaryChainTest()
{
    cout << endl << "******************************dictionaryChainTest()函数开始***********************************" << endl;
    dictionaryChain<int, int> a;
    //测试输入和输出
    cout << endl << "测试输入输出*******************************************" << endl;
    cout << "输入输出************************" << endl;
    cin >> a;
    cout << "dictionaryChain a is:" << a;
    cout << endl << "测试成员函数*******************************************" << endl;
    cout << "empty()*************************" << endl;
    cout << "a.empty() = " << a.empty() << endl;
    cout << "size()**************************" << endl;
    cout << "a.size() = " << a.size() << endl;
    cout << "find()**************************" << endl;
    cout << "a.find(1)->second = " << a.find(1)->second << endl;
    cout << "insert()************************" << endl;
    pair<const int, int> insertData(3,4);
    a.insert(insertData);
    cout << "dictionaryChain a is:" << a;
    cout << "erase()*************************" << endl;
    a.erase(1);
    cout << "dictionaryChain a is:" << a;

    cout << "******************************dictionaryChainTest()函数结束***********************************" << endl;
}

_23pairNode.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月22日09点17分
Last Version:			V1.0
Descriptions:			是字典的一个节点
*/
#pragma once
#ifndef _PAIRNODE_H_
#define _PAIRNODE_H_
using namespace std;
template <class K, class E>
struct pairNode
{
    typedef pair<const K, E> pairType;
    pairType element;
    pairNode<K, E>* next;

    pairNode(const pairType& thePair) :element(thePair) {}
    pairNode(const pairType& thePair, pairNode<K, E>* theNext)
            :element(thePair) {
        next = theNext;
    }
};
#endif

_23dictionary.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月22日09点17分
Last Version:			V1.0
Descriptions:			字典的抽象类
*/
/*
pair:
	介绍:是将2个数据组合成一组数据,是一个结构体,主要的两个成员变量first和second,分别存储两个数据.
	使用:使用std命名空间引入对组std::pair
*/
#pragma once
#ifndef _DICTIONARY_H_
#define _DICTIONARY_H_
using namespace std;
template<class K,class E>
class dictionary
{
public:
    virtual ~dictionary() {}
    /*返回为true,当且仅当字典为空*/
    virtual bool empty() const = 0;
    /*返回字典中数对的数目*/
    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

你可能感兴趣的:(数据结构,算法与应用,C++语言描述学习笔记,数据结构,算法,c++)