大家可否知道,其實查詢中有一種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...