【数据结构】c++实现基于无序链表的符号表查找

本文介绍符号表的概念及其在无序链表中的实现,包括键值对的插入、查找和删除操作。通过使用双向链表,文章详细解释了如何在链表中高效地进行这些基本操作。

符号表

符号表最主要的目的就是将一个键和一个值联系起来。用例能够将一个键值对插入符号表并希望在之后能够从符号表的所有键值对中按照键直接找到对应的值。

要实现符号表,我们首先要定义其背后的数据结构,并指明创建并操作这种数据结构以实现插入、查找等操作所需的算法。

无序链表中的顺序查找

符号表中使用的数据结构的一个简单选择是链表,每个结点存储一个键值对。查找的实现即为遍历链表,比较需被查找的键和每个结点中的键,如果匹配成功返回相应的值,否则返回null。插入的实现也是遍历链表,比较需被查找的键和每个结点中的键,如果匹配成功就用第二个参数指定的值更新和该键相关联的值,否则就用给点的键值对创建一个新的结点并将其插入到链表的开头。

这种方法也被称为顺序查找:在查找中一个一个顺序遍历符号表中的所有键并进行比较来寻找与被查找的键匹配的键。

下面直接看代码:

using namespace std;

template<class T, class K> class SequenyialSearch
{
public:
    SequenyialSearch(){}

    void put(T key, K value){
        //查找给定的键,找到则更新其值,否则在表中新建节点
        for(Node *x = m_pFirst; x != nullptr; x = x->m_pNext){
            if(key == x->m_key){
                x->m_value = value;
                return;
            }
        }
        m_pFirst = new Node(key, value, m_pFirst);
        if(m_pLast){
            m_pLast->m_pPre = m_pFirst;
        }
        m_pLast = m_pFirst;
        N++;
    }

    K get(T key){
        //查找给定的键返回相关联的值
        for(Node *x = m_pFirst; x != nullptr; x = x->m_pNext){
            if(key == x->m_key){
                return x->m_value;
            }
        }
        return K();
    }

    //从表中删去键key及对应的值
    void deleteKey(T key){
        for(Node *x = m_pFirst; x != nullptr; x = x->m_pNext){
            if(key == x->m_key){
                Node *pre = x->m_pPre;
                if(pre){
                    pre->m_pNext = x->m_pNext;
                }
                if(m_pFirst == x){
                    m_pFirst = x->m_pNext;
                    m_pLast = m_pFirst;
                }
                x->m_pNext = nullptr;
                delete x;
                x = nullptr;
                N--;
                return;
            }
        }
    }

    int size() {return N;}
    bool isEmpty() {return size() == 0;}

private:

    //要实现随便删除链表的某个结点,故使用双向链表
    struct Node{
        Node(T key, K value, Node *next):
            m_key(key), m_value(value), m_pNext(next)
        {

        }

        T m_key;
        K m_value;
        Node *m_pNext = nullptr;
        Node *m_pPre = nullptr;
    };

    Node *m_pFirst = nullptr;
    Node *m_pLast = nullptr;
    int N = 0;
};

其中put()为插入,get()为查找,deleteKey()为删除某个元素。如果只实现put和get,只用单向链表即可。要实现deleteKey需要使用双向链表,即遍历整个链表,根据key查找到对应的结点,使该结点的上一个结点指向该结点的下一个结点,再把该结点的资源释放即可,当删除的是第一个结点时,把链表的头结点的指向的上一个结点和指向的下一个结点都置为空,把当前结点资源释放并置为空即可。

看一下运用的代码:

    SequenyialSearch<string, int> search;
    search.put("1", 1);
    search.put("3", 3);
    search.put("5", 5);

    cout << "value:" << search.get("5") << endl;

    search.deleteKey("1");
    cout << "value:" << endl
         << search.get("5") << endl
         << search.get("1") << endl
         << search.get("3") << endl;

运行结果:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值