首页 >> 大全

散列表的原理和应用

2023-12-20 大全 25 作者:考证青年

本来以为,散列表就是map,今天做了道题看答案的时候,才发现我原来搞错了,于是简单的学习了一下散列表的原理和简单实现,发博客分享一下~

我们知道,数组的动态操作(删除、插入)是非常耗时的,链表的静态操作(查找)也是颇为麻烦的。

在既涉及静态操作,又涉及动态操作的场合,这两种基本的数据结构就非常乏力了。

如何达到平衡呢?

我们想象一个场景,在一个特殊的学校里,一开始并没有班级的概念,几千名学生就像是同一个班的。他们有一一对应的学号,

我们顺着他们某一个人的学号找到他们也比较轻松。但问题来了,当有学生转学转走时,这名学生学号后面的其它学生学号要统统减少1,有学生转来时,要统统加上1,这可麻烦透了,怎么解决呢?

我们想,如果将这几千名学生,分成很多个(很多个的原因下面自己体会)班,每个班有自己的学号编排,每个班转走或转来学生,对其它班不会造成影响则,同时,要找到一名学生也并没有变麻烦,只需要找到它对应的班级,在一个班级有限个(有限个的原因自己体会)学生里面一个一个看是不是要找的学生即可。

怎么实现呢?我们将上述场景里的学校想作是一个数组,每个班级是数组里的一个元素,班级想作是一个链表,班级里的学生则是一个又一个节点,查找一个学生的话,先用数组下标定义到学生所在的班级,然后通过链表的遍历找到这名学生。因为班级分的特别多,每个班级里的学生特别少,链表遍历找到这名学生并不是很耗时。如果要删除或者插入一位学生的话,则也是先定位到班级(或应该去的班级)链表遍历到这名学生直接删除,或直接插入。

实现的话我们直接看题目吧。

散列表的实际应用_应用原理表散列在哪_

问题描述

你有一个盒子,你可以往里面放数,也可以从里面取出数。

初始时,盒子是空的,你会依次做 Q 个操作,操作分为两类:

插入操作:询问盒子中是否存在数 x,如果不存在则把数 x 丢到盒子里。删除操作:询问盒子中是否存在数 x,如果存在则取出 x。

对于每个操作,你需要输出是否成功插入或删除。

输入

第一行一个正整数 Q,表示操作个数。

接下来 Q 行依次描述每个操作。每行 2 个用空格隔开的非负整数 op,x 描述一个操作:op 表示操作类型,op=1 则表示这是一个插入操作,op=2 则表示这是一个删除操作;x 的意义与操作类型有关,具体见题目描述。

输出

按顺序对所有操作输出,对于每个操作输出一行,如果成功则输出“”(不含引号),如果失败则输出“”(不含引号)。

样例输入

6
1 100
1 100
2 100
1 200
2 100
2 200

样例输出

Succeeded
Failed
Succeeded
Succeeded
Failed
Succeeded

#include
#include
using namespace std;
typedef long long ll;
const int Mod = 1000003;
vector table[Mod];
int has(int x){return x%Mod;
}
bool check(int op, ll x)
{int h = has(x);vector::iterator ptr = table[h].end();for(vector::iterator it = table[h].begin(); it!=table[h].end(); it++ ){if( *it == x){ptr = it;break;}}if( op == 1){ //插入操作if( ptr!= table[h].end()) //如果已经有这个元素了{return 0;}else//没有的话{table[h].push_back(x);return 1;}}else{ //删除操作if( ptr != table[h].end())//如果有这个元素{*ptr = table[h].back(); //将这个元素被向量最后一个元素替代table[h].pop_back();return 1;}elsereturn 0;}
}
int main()
{int n; scanf("%d",&n);int op; ll x;while(n--){scanf("%d %lld",&op,&x);if( check(op, x)){printf("Succeded\n");}else{printf("Failed\n");}}return 0;
}

因为本人很不喜欢用链表。因此就用向量来模拟了哈。用向量模拟的话,插入操作自然是在向量尾部添加一个元素,只需要O(1)时间,删除的话步骤就像下图所示,因为实际的删除操作是在向量最末端,没有元素需要前移,因此也只需要O(1)的时间

散列表的实际应用_应用原理表散列在哪_

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了