欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言寫一個散列表

 更新時間:2022年01月04日 11:33:23   作者:微小冷  
這篇文章主要介紹了C語言寫一個散列表,散列表,就是下標可以為字母的數組。更多內容和小編一起學習下面內容吧

一、快速理解散列表

散列表,就是下標可以為字母的數組。

假設現有一個數組int a[100],想查找其中第40個元素,則直接輸入a[40]就可以了,時間復雜度為O ( 1 ) O(1)O(1)。

問題在于,當下標不是數字,而是一個字符串的時候,可能需要一個超大的空間才能將所有下標妥善地存放在特定的位置。例如,若以大小寫字母作為下標索引,那么一位就需要預留52個空間,10位就需要52的10次方 這么大的空間,根本沒有設備可以滿足。

好在,52的10次方這么龐大的數字也超出了正常人的使用范圍,無論多長的索引,我們能用上的值也絕對是有限的。

例如,現有下面三個字符串作為下標

key1 = "microcold";
key2 = "tinycold";
key3 = "microcool";

其實只需要選取頭、尾兩個字母,就能很好地區(qū)分這三個字符串,即

def hash(key):
? ? return key[0]+key[-1]

但這種算法對索引字符的要求非常高,至少頭尾不能重復。所以,現在需要能把超長字符串映射成特定短字符串而且盡量避免重復的算法。

二、散列函數

最簡單的散列函數就是求余,將輸入字符串按位轉為整數之后求余。由于在字符串可能會轉成非常大的整數,故需了解余數的性質

(a+b)%c=(a%c+b %c)% c

相應地有:

(a*b)%c=((a%c)*(b %c))% c

用C語言實現如下:

#include <stdio.h>
#define MAXHASH 100

//快速取冪法,a*b^n%c
int ?PowerMod (int a, int b, int n, int c)?
{ ?
? ? int ?ans = 1;?
? ? b = b % c;?
? ? while (n > 0) { ?
? ? ? ? if(n % 2 == 1)?
? ? ? ? ? ? ans = (ans * b) % c;?
? ? ? ? n = n / 2; ? ? ? //b >>= 1;
? ? ? ? b = (b * b) % c;?
? ? }?
? ? return (a*ans)%c;?
}?

int hash(char* key, int n){
? ? int addr = 0;
? ? for(int i = 0; i < n; i++){
? ? ? ? addr += PowerMod(key[i], 128, i, MAXHASH);
? ? }
? ? return addr%MAXHASH;
}

int main(){
? ? char* str;
? ? int i;
? ? while(1){
? ? ? ? gets(str);
? ? ? ? i = 0;
? ? ? ? while(str[i++]!='\0'){}
? ? ? ? printf("%d\n",hash(str,i));
? ? }
? ? return 0;
}

測試如下:

>gcc hash.c
>a.exe
asdf
21
microcold
81
tinycold
12
microcool
5
minicool
81
minicold
73

三、防撞

盡管minicool和microcold撞車了,但通過100以內的位數,去表示52的9次方 的樣本,也算是不錯的表現了。

為了不發(fā)生撞車,則需更改數組中的元素類型——至少得是個結構體。而防止撞車的方法很簡單,如果發(fā)生撞車,那我就不散列了,直接發(fā)配到一個指定的數組中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXHASH 100
typedef struct HASHNODE{
? ? char *key;
? ? int next;
} *hashNode;

struct HASHNODE* hashTable[MAXHASH];
struct HASHNODE* crashTable[MAXHASH]; ? ? //存儲撞擊之后的值
int numCrash=0; ? ? ? ? ? ? ? ? ? //已有的撞擊值

void initTable(){
? ? for(int i=0; i < MAXHASH; i++){
? ? ? ? hashTable[i] = (hashNode)malloc(sizeof(struct HASHNODE));
? ? ? ? hashTable[i]->key = NULL;
? ? ? ? hashTable[i]->next = -1;
? ? ? ? crashTable[i] = (hashNode)malloc(sizeof(struct HASHNODE));
? ? ? ? crashTable[i]->key = NULL;
? ? ? ? hashTable[i]->next = -1;
? ? }
}

void insertCrash(char* str, int index, int n){
? ? if(index == numCrash){
? ? ? ? crashTable[numCrash]->key = (char*)malloc(sizeof(char)*n);
? ? ? ? strcpy(crashTable[numCrash++]->key, str); ?//此時新增一個節(jié)點
? ? }
? ? else {
? ? ? ? if(crashTable[index]->next==-1)
? ? ? ? ? ? crashTable[index]->next = numCrash;
? ? ? ? insertCrash(str, hashTable[index]->next, n);
? ? }
}

//n為字符串長度
void insertHash(char* str, int index,int n){
? ? if(hashTable[index]->key==NULL){
? ? ? ? hashTable[index]->key = (char*)malloc(sizeof(char)*n);
? ? ? ? strcpy(hashTable[index]->key, str);
? ? }else{
? ? ? ? if(hashTable[index]->next==-1)
? ? ? ? ? ? hashTable[index]->next = numCrash;
? ? ? ? insertCrash(str, hashTable[index]->next, n);
? ? }
}

void printHash(){
? ? for(int i = 0; i < MAXHASH; i++){
? ? ? ? if(hashTable[i]->key!=NULL)
? ? ? ? ? ? printf("hashTable[%d]:%s\n",i,hashTable[i]->key);
? ? ? ? if(crashTable[i]->key!=NULL)
? ? ? ? ? ? printf("crashTable[%d]:%s\n",i,crashTable[i]->key);
? ? }
}

int ?PowerMod (int a, int b, int n, int c)?
{ ?
? ? int ?ans = 1;?
? ? b = b % c;?
? ? while (n > 0) { ?
? ? ? ? if(n % 2 == 1)?
? ? ? ? ? ? ans = (ans * b) % c;?
? ? ? ? n = n / 2; ? ? ? //b >>= 1;
? ? ? ? b = (b * b) % c;?
? ? }?
? ? return (a*ans)%c;?
}?

int hash(char* key, int n){
? ? int addr = 0;
? ? for(int i = 0; i < n; i++){
? ? ? ? addr += PowerMod(key[i], 128, i, MAXHASH);
? ? }
? ? return addr%MAXHASH;
}

int main(){
? ? initTable();
? ? char* str;
? ? int i;
? ? while(1){
? ? ? ? gets(str);
? ? ? ? if(strcmp(str,"exit")==0) break;
? ? ? ? i = 0;
? ? ? ? while(str[i++]!='\0'){}
? ? ? ? insertHash(str,hash(str,i),i);
? ? ? ? printf("%d\n",hash(str,i));
? ? }
? ? printHash();
? ? return 0;
}

最后得到:

>gcc hash.c
>a.exe
asdf
21
hellworld
84
microcold
81
minicool
81
tinycool
20
tinycold
12
weixiaoleng
11
exit
crashTable[0]:minicool
hashTable[11]:weixiaoleng
hashTable[12]:tinycold
hashTable[20]:tinycool
hashTable[21]:asdf
hashTable[81]:microcold
hashTable[84]:hellworld

可見一方面的確散列了,另一方面也的確防撞了。

到此這篇關于C語言寫一個散列表的文章就介紹到這了,更多相關C語言寫散列表內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言+EasyX實現數字雨效果

    C語言+EasyX實現數字雨效果

    這篇文章主要為大家詳細介紹了C語言+EasyX實現數字雨效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • c語言定時器示例分享

    c語言定時器示例分享

    在linux下開發(fā),使用的是C語言。適用于需要定時的軟件開發(fā),以系統真實的時間來計算,它送出SIGALRM信號。每隔一秒定時一次
    2014-04-04
  • C語言數據結構二叉樹先序、中序、后序及層次四種遍歷

    C語言數據結構二叉樹先序、中序、后序及層次四種遍歷

    這篇文章主要介紹了C語言數據結構二叉樹先序、中序、后序及層次四種遍歷方式,具有一定的知識性參考價值,需要的小伙伴可以先看一下
    2022-02-02
  • C語言實現用戶態(tài)線程庫案例

    C語言實現用戶態(tài)線程庫案例

    下面小編就為大家?guī)硪黄狢語言實現用戶態(tài)線程庫案例。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • C++中l(wèi)ist的用法實例講解

    C++中l(wèi)ist的用法實例講解

    list是順序容器的一種,list是一個雙向鏈表,使用list需要包含頭文件list,這篇文章主要給大家介紹了關于C++中l(wèi)ist的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-11-11
  • 詳解C++中的數據抽象

    詳解C++中的數據抽象

    這篇文章主要介紹了詳解C++中的數據抽象,數據抽象是指,只向外界提供關鍵信息,并隱藏其后臺的實現細節(jié),即只表現必要的信息而不呈現細節(jié),需要的朋友可以參考下
    2023-05-05
  • QT實現自定義Http客戶端的示例代碼

    QT實現自定義Http客戶端的示例代碼

    這篇文章主要為大家詳細介紹了QT如何實現自定義Http客戶端的,可以實現支持get,post請求方式;支持連接超時處理;支持網絡錯誤,嘗試重連等功能,感興趣的小伙伴可以學習一下
    2022-11-11
  • C語言實現動態(tài)順序表的示例代碼

    C語言實現動態(tài)順序表的示例代碼

    順序表是用一段物理地址連續(xù)的存儲單元依次存儲數據元素的線性結構。順序表一般分為靜態(tài)順序表和動態(tài)順序表,本文主要和大家介紹的是動態(tài)順序表的實現,需要的可以參考一下
    2022-10-10
  • 基于Matlab圖像處理的公路裂縫檢測實現

    基于Matlab圖像處理的公路裂縫檢測實現

    隨著公路的大量投運,公路日常養(yǎng)護和管理已經成為制約公路運營水平提高的瓶頸,特別是路面狀態(tài)采集、檢測維護等工作更是對傳統的公路運維模式提出了挑戰(zhàn)。這篇文章主要介紹了如何通過Matlab圖像處理實現公路裂縫檢測,感興趣的可以了解一下
    2022-02-02
  • C++ 使用new與delete需注意的原則

    C++ 使用new與delete需注意的原則

    這篇文章主要介紹了C++ 使用new與delete需注意的原則,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下
    2020-08-08

最新評論