zoukankan      html  css  js  c++  java
  • 【哈希表】CodeVs1230元素查找

    一、写在前面

    哈希表(Hash Table),又称散列表,是一种可以快速处理插入和查询操作的数据结构。哈希表体现着函数映射的思想,它将数据与其存储位置通过某种函数联系起来,其在查询时的高效性也体现在这里。换言之,我们建立一个函数关系(称之为散列函数):data—>address,将数据和其存储位置关联;查询时,我们只需要根据我们建立的函数关系就能通过data查询到address。

    可见,散列函数的建立直接影响着哈希表的效率。当我们的散列函数建立得足够优时,哈希表在插入和查询上的时间复杂度都能被降为O(1)。常用的建立散列函数的方法有如下几种:

    1、直接寻址法:直接取数据或数据的某种线性函数作为散列函数;

    2、平方取中法:对数据平方,取其中间几位作为散列函数;

    3、折叠法:将数据拆开成几部分,再重新组合;

    4、除留取余法:用数据对一个大质数取模,将余数作为散列函数。 

    本篇blog采用除留取余法建立散列函数。

    显然,由于函数是一种允许多个自变量对应同一应变量的关系,在插入和查询时,存储位置的冲突便不可避免。当发生冲突时,我们通常用以下两种方法解决:

    1、错位法:即当正在读入的数据与以前已经插入表中的数据冲突时,我们从发生冲突的存储位置开始向某个方向寻找一个空存储位置,将当前读入的数据插入其中;

    2、拉链法:结合链表的思想,将所有相互发生冲突的数据拉成一条链。

    哈希表的优点很明显,就是它在插入和查询室常数级别的时间复杂度。然而它的缺点也很明显,包括无法存储相同的元素,无法排序,而且极占用空间。所以想要熟练运用哈希表也不是一件容易的事情,下面我们不妨看一道模板题。

    二、题目

    Description

    给出n个正整数,然后有m个询问,每个询问一个整数,询问该整数是否在n个正整数中出现过。

    Input Description

    第一行两个整数 n 和m。

    第二行n个正整数(1<=n<= 100000)

    第三行m个整数(1<=m<=100000)

    Output Description

    一共m行,若出现则输出YES,否则输出NO

    Sample Input

    4 2

    2 1 3 4

    1 9

    Sample Output

    YES

    NO

    Data Size & Hint

    所有数据都不超过10^8

    附上原题链接→_→|1230 元素查找|CODEVS,算法爱好者社区

    三、代码实现

     1 #include<stdio.h>
     2 #define MAX 100010
     3 #define p 10000007
     4 int n,m;
     5 struct node 
     6 {
     7     int next;
     8     int data;
     9 };
    10 int st[p],cnt;
    11 node tab[MAX];
    12 int ans;
    13 int getHashAddress(int x){return x%p;}//散列函数 
    14 void insert(int x)//插入元素 
    15 {
    16     int address=getHashAddress(x);
    17     for(int i=st[address];i;i=tab[i].next)//判断元素是否在表中 
    18         if(tab[i].data==x)return;
    19     tab[++cnt].next=st[address];//拉链 
    20     st[address]=cnt;
    21     tab[cnt].data=x;
    22 }
    23 bool find(int x)//查询元素 
    24 {
    25     int address=getHashAddress(x);
    26     for(int i=st[address];i;i=tab[i].next)
    27         if(tab[i].data==x)return true;
    28     return false; 
    29 }
    30 int main()
    31 {
    32     scanf("%d%d",&n,&m);
    33     for(int i=1;i<=n;++i)
    34     {
    35         int x;
    36         scanf("%d",&x);
    37         insert(x);
    38     }
    39     for(int i=1;i<=m;++i)
    40     {
    41         int x;
    42         scanf("%d",&x);
    43         if(find(x))printf("YES");
    44         else       printf("NO");
    45         printf("
    ");
    46     }
    47     return 0;
    48 } 
    CodeVs1230 元素查找

    弱弱地说一句,本蒟蒻码字也不容易,转载请注明出处http://www.cnblogs.com/Maki-Nishikino/p/5999356.html

  • 相关阅读:
    编程思想之多线程与多进程——以操作系统的角度述说线程与进程
    git 版本回退
    git 版本回退
    求助帖:android开发初期:为什么我在活动二设置的singInstance模式跑到活动三去了???
    求助帖:android开发初期:为什么我在活动二设置的singInstance模式跑到活动三去了???
    Android初学:Gradle 'HelloWorld' project refresh failed
    处理日期时间方法总结
    解决error104 connection reset by peer;socket error问题
    'utf8' codec can't decode byte 0xd1 in position 931: invalid continuation byte解决方法
    scrapy学习笔记
  • 原文地址:https://www.cnblogs.com/Maki-Nishikino/p/5999356.html
Copyright © 2011-2022 走看看