演算法系列15天速成 第五天 五大經典查詢 中

2021-09-23 21:25:19 字數 3773 閱讀 1272

大家可否知道,其實查詢中有一種o(1)的查詢,即所謂的秒殺。

雜湊查詢:

對的,他就是雜湊查詢,說到雜湊,大家肯定要提到雜湊函式,呵呵,這東西已經在我們腦子裡面形成

固有思維了。大家一定要知道「雜湊「中的對應關係。

比如說: 」5「是乙個要儲存的數,然後我丟給雜湊函式,雜湊函式給我返回乙個」2",那麼此時的」5「

和「2」就建立一種對應關係,這種關係就是所謂的「雜湊關係」,在實際應用中也就形成了」2「是key,」5「是value。

那麼有的朋友就會問如何做雜湊,首先做雜湊必須要遵守兩點原則:

①:  key盡可能的分散,也就是我丟乙個「6」和「5」給你,你都返回乙個「2」,那麼這樣的雜湊函式不盡完美。

②: 雜湊函式盡可能的簡單,也就是說丟乙個「6」給你,你雜湊函式要搞1小時才能給我,這樣也是不好的。

其實常用的做雜湊的手法有「五種」:

第一種:」直接定址法「。

很容易理解,key=value+c; 這個「c"是常量。value+c其實就是乙個簡單的雜湊函式。

第二種:「除法取餘法」。

很容易理解, key=value%c;解釋同上。

第三種:「數字分析法」。

這種蠻有意思,比如有一組value1=112233,value2=112633,value3=119033,

針對這樣的數我們分析數中間兩個數比較波動,其他數不變。那麼我們取key的值就可以是

key1=22,key2=26,key3=90。 

第四種:「平方取中法」。此處忽略,見名識意。

第五種:「摺疊法」。

這種蠻有意思,比如value=135790,要求key是2位數的雜湊值。那麼我們將value變為13+57+90=160,

然後去掉高位「1」,此時key=60,哈哈,這就是他們的雜湊關係,這樣做的目的就是key與每一位value都相

關,來做到「雜湊位址」盡可能分散的目地。

正所謂常在河邊走,哪有不濕鞋。雜湊也一樣,你雜湊函式設計的再好,搞不好哪一次就撞樓了,那麼拋給我們的問題

就是如果來解決「雜湊位址「的衝突。

其實解決衝突常用的手法也就2種:

第一種: 「開放位址法「。

所謂」開放位址「,其實就是陣列中未使用的位址。也就是說,在發生衝突的地方,後到的那個元素(可採用兩種方式

:①線性探測,②函式探測)向陣列後尋找"開放位址「然後把自己插進入。

第二種:」鏈結法「。

這個大家暫時不懂也沒關係,我就先介紹一下原理,就是在每個元素上放乙個」指標域「,在發生衝突的地方,後到的那

個元素將自己的資料域拋給衝突中的元素,此時衝突的地方就形成了乙個鍊錶。

上面囉嗦了那麼多,也就是想讓大家在」設計雜湊「和」解決衝突「這兩個方面提一點參考和手段。

那麼下面就上**了,

設計函式採用:」除法取餘法「。

衝突方面採用:」開放位址線性探測法"。

using system;

using system.collections.generic;

using system.linq;

using system.text;

namespace hashsearch

; //雜湊表長度

static int hash = new int[hashlength];

static void main(string args)

console.writeline("hash資料:" + string.join(",", hash));

while (true)

}////// hash表檢索資料

//////

//////

/// static int searchhash(int hash, int hashlength, int key)

//查詢到了開放單元,表示查詢失敗

if (hash[hashaddress] == 0)

return -1;

return hashaddress;

}//////資料插入hash表

//////雜湊表

//////

static void inserthash(int hash, int hashlength, int data)

//將data存入字典中

hash[hashaddress] = data;}}

}

結果:

索引查詢:

一提到「索引」,估計大家第一反應就是「資料庫索引」,對的,其實主鍵建立「索引」,就是方便我們在海量資料中查詢。

關於「索引」的知識,估計大家都比我清楚,我就簡單介紹下。

我們自己寫演算法來實現索引查詢時常使用的三個術語:

第一:主表,      這個很簡單,要查詢的物件。

第二:索引項,   一般我們會用函式將乙個主表劃分成幾個子表,每個子表建立乙個索引,這個索引叫做索引項。

第三:索引表,    索引項的集合也就是索引表。

一般「索引項」包含三種內容:index,start,length

第一: index,也就是索引指向主表的關鍵字。

第二:start, 也就是index在主表中的位置。

第三:length, 也就是子表的區間長度。

using system;

using system.collections.generic;

using system.linq;

using system.text;

namespace indexsearchprogram

static void main(string args)

console.readline();

}////// 學生主表

/// static int students = ;

//////學生索引表

/// static indexitem indexitem = ,

new indexitem(),

new indexitem(),

};////// 查詢資料

//////

/// public static int indexsearch(int key)

;break;}}

//如果item為null,則說明在索引中查詢失敗

if (item == null)

return -1;

for (int i = item.start; i < item.start + item.length; i++)

}return -1;

}////// 插入資料

//////

/// public static int insert(int key)

;break;}}

if (item == null)

return -1;

//更新主表

students[item.start + item.length] = key;

//更新索引表

indexitem[i].length++;

return 1;}}

}

結果:

ps: 雜湊查詢時間複雜度o(1)。

索引查詢時間複雜度:就拿上面的demo來說是等於o(n/3)+o(length)

演算法系列15天速成 第五天 五大經典查詢 中

大家可否知道,其實查詢中有一種o 1 的查詢,即所謂的秒殺。雜湊查詢 對的,他就是雜湊查詢,說到雜湊,大家肯定要提到雜湊函式,呵呵,這東西已經在我們腦子裡面形成 固有思維了。大家一定要知道 雜湊 中的對應關係。比如說 5 是乙個要儲存的數,然後我丟給雜湊函式,雜湊函式給我返回乙個 2 那麼此時的 5...

演算法系列15天速成 第五天 五大經典查詢 中

原文 演算法系列15天速成 第五天 五大經典查詢 中 大家可否知道,其實查詢中有一種o 1 的查詢,即所謂的秒殺。雜湊查詢 對的,他就是雜湊查詢,說到雜湊,大家肯定要提到雜湊函式,呵呵,這東西已經在我們腦子裡面形成 固有思維了。大家一定要知道 雜湊 中的對應關係。比如說 5 是乙個要儲存的數,然後我...

演算法系列15天速成 第四天 五大經典查詢 上

在我們的生活中,無處不存在著查詢,比如找一下班裡哪個mm最pl,猜一猜mm的芳齡.對的這些都是查詢。在我們的演算法中,有一種叫做線性查詢。分為 順序查詢。折半查詢。查詢有兩種形態 分為 破壞性查詢,比如有一群mm,我猜她們的年齡,第一位猜到了是23 此時這位mm已經從我腦海裡面的mmlist中rem...