zoukankan      html  css  js  c++  java
  • 第七章小结

    第七章学习了根据存储结构的查找方法及其实现的算法。散列表的查找(hashing)是我们学习的内容之一。散列表是一个有连续的地址空间,用于存储按散列函数计算得到相应散列地址的数据记录。通常其存储空间是一维数组,散列地址是数组下标。

    冲突和同义词:对于不同关键字可能得到同一散列地址,这种现象称为冲突。具有相同函数值的关键字对该散列表函数来说成为同义词。

    解决冲突的方法有1.开放地址法:线性探测法,二次探测法;2.链地址法(一维数组+链表)

    其中在这次作业中将关键字插入散列表,用二分探测法输出关键字所在的地址下标,若无法插入则输出-”。

    二分探测法:H(i)=(H(key)+d(i))%length,d(i)=1^2,-1^2,2^2,-2^2.....在数组的前后找空单元,插入关键字。

    typedef struct
    {//定义散列表结构体 
        int key[N];//关键字
        int length;//长度
    }hashtable;
    View Code//散列表结构定义

    建立一个散列表,并将所有关键字置0,根据关键字是否为0判断它是否已插入数据。

    int Init(hashtable &h,int m)
    {//初始化散列表元素为0 
        m=nextprime(m);//将输入的散列表长度转化为素数 
        h.length=m;
        for(int i=0;i<m;i++)
          h.key[i]=0;
    }
    View Code//建立及初始化关键字

    插入关键字函数,注意使用引用符号&(一开始没有加上&,数据根本没有插入散列表)。输出时则注意格式要求。

    void insert(hashtable &h,int num)
    {//元素出入并输出元素对应位置的下标 
        int pos=Hash(num,h.length);//求余 
        int tempos=pos;//辅助变量 
        if(h.key[tempos]==0)
        {//若在下标tempos处无元素,则插入num 
            h.key[tempos]=num;
            cout<<pos;
        }
        
        else
        {//否则用二分法获得另一个可插入的下标pos 
            int x,flag=0;//flag判断元素是否能插入散列表 
            for(x=1;x<h.length;x++)
            {
                pos=(tempos+x*x)%h.length;//二分法 
                if(h.key[pos]==0)
                {
                    flag=1;
                    h.key[pos]=num;
                    cout<<pos;
                    break;
                }
            }
            //flag=0证明无法插入该元素,输出- 
            if(flag==0)
              cout<<"-";
        }
    }
    View Code//插入数据并输出所在下标
    int Hash(int key,int length)
    {//获得映射 
        return key%length;//求余 
    }
    View Code//求余获得映射

    散列表的长度为素数时能有效的减少冲突,因此将输入的长度m转化为素数。

    int nextprime(int num)
    {//将输入的散列表长度转变为素数,并获得该素数 
        if(num==1)
          return 2;
        int i,p;
        p=num%2==1?num:num+1;
        while(1)
        {
            for(i=sqrt(p);i>=2;i--)
              if(p%i==0)  break;
            if(i==1)  break;
            
            else  p=p+2;
        }
        return p;
    }
    View Code//长度为素数

    主函数

    int main()
    {
        hashtable h;
        int m,n,pos,num;
        cin>>m>>n;//输入散列表的长度,成员数目 
        Init(h,m);//初始化散列表 
        
        for(int i=0;i<n;i++)
        {
            if(i!=0)  cout<<" ";//格式化输出 
            cin>>num;
            insert(h,num);//将num插入散列表并输出 
        }
        //cout<<h.key[0];
        
        return 0;
    }
    View Code

    我出现的错误有引用符号未使用(通过输出散列表其中一个关键字判断),以及函数名冲突问题(hash)。

    主要是参考他人的博客和CSDN。

  • 相关阅读:
    Representation Data in OpenCascade BRep
    Render OpenCascade Geometry Surfaces in OpenSceneGraph
    Render OpenCascade Geometry Curves in OpenSceneGraph
    OpenCascade Shape Representation in OpenSceneGraph
    Geometry Surface of OpenCascade BRep
    Geometry Curve of OpenCascade BRep
    Tyvj2017清北冬令营入学测试
    Spfa算法模板
    洛谷1016 旅行家的预算
    洛谷1290 欧几里得的游戏
  • 原文地址:https://www.cnblogs.com/liuyuany/p/10964961.html
Copyright © 2011-2022 走看看