【数据结构与算法】散列查找——线性探测/链接地址解决冲突

一次简单的散列查找习题


前言

在地址空间为0~16的散列区中,对以下关键字序列构造两个哈希表:

(Jan, Feb, Mar, Apr, May, June, July, Aug, Sep, Oct, Nov, Dec)   

(1)用线性探测开放定址法处理冲突;   

(2)用链地址法处理。


一、.h文件

#ifndef __HASH_H__
#define __HASH_H__

#include <iostream>
#include <cstring>
using namespace std;
struct Node
{
    char Str[50];
    Node* Next;
    Node()
    {
        Str[0]=0;
        Next=NULL;
    }
};

class HashTable
{
private:
    char table[17][20];
    Node* table2;
    bool Switch;    // 2 kinds of search & insert
    bool* sign; 
    bool* sign2;
    bool test_key;
public:
    HashTable();
    int Hash(char str[]);
    void HashInsert(char str[]);
    bool getSign(int index);
    bool getSign2(int index);
    bool getSwitch();
    void reverseSwitch();
    void signMark(int index);
    void sign2Mark(int index);
    bool whetherInTable(char str[]);
};

HashTable::HashTable()
{
    test_key=false;
    //table = new char* [16]; 
    sign = new bool [17];
    table2 = new Node [17];
    sign2 = new bool [17];
    for(int i=0;i<16;++i)
    {
        table[i][0]=0;
        sign[i]=true;
        sign2[i]=true;
    }
    Switch=false;
    if(test_key)cout<<"Initialize HashTable object successfully!\n";
}
bool HashTable::whetherInTable(char str[])
{
    int index=Hash(str);
    if(index<0 || index>=17)return false;
    if(getSwitch())
    {
        while(!getSign(index) && strcmp(table[index],str)!=0 )
        {
            index=(index+1)%17;
        }
        if(strcmp(table[index],str)==0)return true;
        return false;
    }
    else
    {
        if(getSign2(index))return false;
        Node* ptr=&table2[index];
        while(ptr!= NULL && strcmp(ptr->Str,str)!=0)
        {
            ptr=ptr->Next;
            //cout<<ptr<<" ";
        }
        if(ptr==NULL)return false;
        return true;
    }
}

void HashTable::signMark(int index){sign[index]=false;}

void HashTable::sign2Mark(int index){sign2[index]=false;}

void HashTable::reverseSwitch(){Switch=!Switch;}

bool HashTable::getSwitch(){return Switch;}

int HashTable::Hash(char str[])
{
    char first=str[0];
    return (first-'A'+1)/2;
}

void HashTable::HashInsert(char str[])
{
    int index=Hash(str);
    if(index<0 || index>=17)return;
    if(getSwitch())
    {
        while(!getSign(index))
        {
            index=(index+1)%17;
        }
        strcpy(table[index],str);
        signMark(index);
    }
    else
    {
        if(getSign2(index))
        {
            strcpy(table2[index].Str,str);
            sign2Mark(index);
        }
        else
        {
            Node* now = &table2[index];
            while(now->Next!=NULL)
            {
                now=now->Next;
            }
            Node* newNode = new Node;
            newNode->Next=NULL;
            now->Next=newNode;
            strcpy(newNode->Str,str);
        }
    }
    if(test_key)cout<<"Insert element in HashTable object successfully!\n";
}

bool HashTable::getSign(int index){return sign[index];}

bool HashTable::getSign2(int index){return sign2[index];}
#endif

二、.cpp文件

#include <iostream>
#include "Hash.h"

using namespace std;

int main()
{
    char strlist[12][10];
    cout<<"请输入要存储的字符串元素(规制下才有效存储):";
    for(int i=1;i<=12;++i)
    {
        cin>>strlist[i-1];
        //cout<<strlist[i-1];
    }

    HashTable htable;
    // if(htable.getSwitch())cout<<"线性探测法处理冲突:\n";
    // else cout<<"链表地址法处理冲突:\n";
    for(int i=0;i<12;++i)
    {
        htable.HashInsert(strlist[i]);
    }

    htable.reverseSwitch();
    // if(htable.getSwitch())cout<<"线性探测法处理冲突:\n";
    // else cout<<"链表地址法处理冲突:\n";
    for(int i=0;i<12;++i)
    {
        htable.HashInsert(strlist[i]);
    }    
    char que[50];

    htable.reverseSwitch();
    cout<<"线性探测法处理冲突(输入quit退出):\n";
    while(true)
    {
        cout<<"请输入查询:";
        cin>>que;
        if(strcmp(que,"quit")==0)break;
        cout<<"查询结果:"<<(htable.whetherInTable(que)?"在表内":"不在表内")<<endl;
    }

    htable.reverseSwitch();
    cout<<"链表地址法处理冲突(输入quit退出):\n";
    while(true)
    {
        cout<<"请输入查询:";
        cin>>que;
        if(strcmp(que,"quit")==0)break;
        cout<<"查询结果:"<<(htable.whetherInTable(que)?"在表内":"不在表内")<<endl;
    }
    return 0;
}

//Jan Feb Mar Apr May June July Aug Sep Oct Nov Dec

  并分别求这两个哈希表在等概率情况下查找成功和不成功时的平均查找长度。   设哈希函数为H(x)= └i/2┘,其中i为关键字中第一个字母在字母表中的序号。

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值