28、數據結構與算法 - 散列查詢

散列技術

散列技術是記錄的存儲位置和他的關鍵字之間建立一個確定的對應關係f,使得每個關鍵字key對應一個存儲位置f(key)。查找時,根據這個對應關係找到給定位置key的映射f(key)。若炒作集合中存在這個記錄,則必定在f(key)的位置上

1、

2、直接地址法

f(key) = a*key + b(a,b爲常數);

 

3、

4、

5、

6、

7、

8、

 

9、

連地址法:
將所有的關鍵字爲同義詞的記錄存儲在一個單鏈表中,我們成爲這種同義詞子表。在散列表中只存儲所有同義詞子表的頭指針(頭地址)。

#include "stdio.h"
#include "stdlib.h"

#include "math.h"
#include "time.h"

typedef int Status;

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 //存儲空間初始分配量
#define SUCCESS 1
#define UNSUCCESS 0

//定義散列表長爲數組的長度
#define HASHSIZE 12
#define NULLKEY -32768

typedef struct
{
    //數據元素存儲基址,動態分配數組
    int *elem;
    //當前數據元素個數
    int count;
}HashTable;
int m=0; /* 散列表表長,全局變量 */

初始化散列表

//1.初始化散列表
Status InitHashTable(HashTable *H)
{
    int i;
    
    //① 設置H.count初始值; 並且開闢m個空間
    m=HASHSIZE;
    H->count=m;
    H->elem=(int *)malloc(m*sizeof(int));
    
    //② 爲H.elem[i] 動態數組中的數據置空(-32768)
    for(i=0;i<m;i++)
        H->elem[i]=NULLKEY;
    
    return OK;
}
//2. 散列函數
int Hash(int key)
{
    //除留餘數法
    return key % m;
}
//3. 插入關鍵字進散列表
void InsertHash(HashTable *H,int key)
{
    
    
    //① 求散列地址
    int addr = Hash(key);
    
    //② 如果不爲空,則衝突
    while (H->elem[addr] != NULLKEY)
    {
        //開放定址法的線性探測
        addr = (addr+1) % m;
    }
    
    //③ 直到有空位後插入關鍵字
    H->elem[addr] = key;
}
//4. 散列表查找關鍵字
Status SearchHash(HashTable H,int key,int *addr)
{
    //① 求散列地址
    *addr = Hash(key);
    
    //② 如果不爲空,則衝突
    while(H.elem[*addr] != key)
    {
        //③ 開放定址法的線性探測
        *addr = (*addr+1) % m;
        
        //④H.elem[*addr] 等於初始值或者循環有回到了原點.則表示關鍵字不存在;
        if (H.elem[*addr] == NULLKEY || *addr == Hash(key))
            //則說明關鍵字不存在
            return UNSUCCESS;
    }
    
    return SUCCESS;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    int arr[HASHSIZE]={12,67,56,16,25,37,22,29,15,47,48,34};
    int i,p,key,result;
    HashTable H;
    
    //1.初始化散列表
    InitHashTable(&H);
    
    //2.向散列表中插入數據
    for(i=0;i<m;i++)
        InsertHash(&H,arr[i]);
    
    //3.在散列表查找key=39
    key=39;
    result=SearchHash(H,key,&p);
    if (result)
        printf("查找 %d 的地址爲:%d \n",key,p);
    else
        printf("查找 %d 失敗。\n",key);
    
    //4.將數組中的key,打印出所有在散列表的存儲地址
    for(i=0;i<m;i++)
    {
        key=arr[i];
        SearchHash(H,key,&p);
        printf("查找 %d 的地址爲:%d \n",key,p);
    }

    return 0;
}
Hello, World!
查找 39 失敗。
查找 12 的地址爲:0 
查找 67 的地址爲:7 
查找 56 的地址爲:8 
查找 16 的地址爲:4 
查找 25 的地址爲:1 
查找 37 的地址爲:2 
查找 22 的地址爲:10 
查找 29 的地址爲:5 
查找 15 的地址爲:3 
查找 47 的地址爲:11 
查找 48 的地址爲:6 
查找 34 的地址爲:9 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章