a(0
<
a<1)
,並抽取出key.a的小數部分;然後用m乘以該小數後取整。即: h(
key)
=m∗⌊
key∗
a−⌊k
ey∗a
⌋⌋該方法最大的優點是m的選取比除餘法要求更低。
3)除法
取關鍵字被數p除后所得餘數為雜湊址:h(
key)
=key
modp
,不太常用,因為除法的效率比乘法低,乘數相乘法更合適。
4)分段疊加法
將關鍵字分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(捨去進製)作為雜湊位址,這方法稱為摺疊法(folding)。
5)偽隨機
選擇乙個隨機函式,取關鍵字的隨機函式值為它的雜湊位址,即h(
key)
=ran
dom(
key)
,其中random為隨機函式。通常,當關鍵字長度不等時採用此法構造雜湊函式較恰當。
6)查表法
有乙個關鍵字表,通過關鍵字可以在該錶查詢hash值
7)平方取中法
取關鍵字平方後的中間幾位為雜湊位址。
解決衝突
1)開放位址法
a)線性探測法
插入元素時,如果發生衝突,演算法會簡單的從該槽位置向後迴圈遍歷hash表,直到找到表中的下乙個空槽,並將該元素放入該槽中,這會使得相同hash值的元素緊挨在一起導致其他hash值的槽被占用。查詢元素時,首先雜湊值所指向的槽,如果沒有找到匹配,則繼續從該槽遍歷hash表,直到:(1)找到相應的元素;(2)找到乙個空槽,指示查詢的元素不存在,(所以不能隨便刪除元素);(3)整個hash表遍歷完畢(指示該元素不存在並且hash表是滿的)
缺點:
①處理溢位需另程式設計序。一般可另外設立乙個溢位表,專門用來存放上述雜湊表中放不下的記錄。此溢位表最簡單的結構是順序表,查詢方法可用順序查詢。
②刪除工作非常困難。如果將此元素刪除,查詢的時會發現空槽,則會認為要找的元素不存在。只能標上已被刪除的標記,否則,將會影響以後的查詢。
③容易產生堆聚現象。所謂堆聚現象,就是存入雜湊表的記錄在表中連成一片。按照線性探測法處理衝突,如果生成雜湊位址的連續序列愈長 ( 即不同關鍵字值的雜湊位址相鄰在一起愈長 ) ,則當新的記錄加入該錶時,與這個序列發生衝突的可能性愈大。因此,雜湊位址的較長連續序列比較短連續序列生長得快,這就意味著,一旦出現堆聚 ( 伴隨著衝突 ) ,就將引起進一步的堆聚。
b)線性補償探測法
基本思想是:將線性探測的步長從1改為q,即將上述演算法中的ha
sh=(
hash
+1)%
m 改為:ha
sh=(
hash
+q)%
m=ha
sh%m
+q%m
,而且要求 q 與 m 是互質的,以便能探測到雜湊表中的所有單元。
c)偽隨機探測
基本思想是:將線性探測的步長從常數改為隨機數,即令: ha
sh=(
hash
+rn)
%m排序方式
最壞時間複雜度
空間複雜度
穩定性氣泡排序
o(n^2)
o(1)
穩定選擇排序
o(n^2)
o(1)
不穩定插入排序
o(n^2)
o(1)
穩定希爾排序
o(n^2)
o(1)
不穩定歸併排序
o(n*lgn)
o(n)
穩定快速排序
o(n^2)
o(lgn)
不穩定堆排序
o(n*lgn)
o(1)
不穩定桶排序
o()o()
o()計數排序
o()o()
o()
/**
* 氣泡排序
* 思路:內部迴圈每走一趟排好一位,依次向後排序
*/private
static
void
bubblesort(int data) }}
}
/**
* 選擇排序
* 思路:每次迴圈得到最小值的下標,然後交換資料。
* 如果交換的位置不等於原來的位置,則不交換。
*/public
static
void
selectsort(int data)
}if (index != i)
}}
/**
* 插入排序
* 思路:將資料插入到已排序的陣列中。
*/public
static
void
insertsort(int data)
//內部迴圈結束,找到插入的位置賦值即可。
data[j]=temp;
}}
參考:白話經典演算法系列之三 希爾排序的實現
希爾排序的實質就是分組插入排序,該方法又稱縮小增量排序,因dl.shell於2023年提出而得名。基本思想:先將整個待排元素序列分割成若干個子串行(由相隔某個「增量」的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。因為直接插入排序在元素基本有序的情況下(接近最好情況),效率是很高的。
/**
* 希爾排序(縮減增量排序)
* 想想也不難。
* 思路:三層迴圈
* 第一層迴圈:控制增量-增量隨著程式的進行依次遞減一半
* 第二層迴圈:遍歷陣列
* 第三層迴圈:比較元素,交換元素。
* 這裡需要注意的是:比較的兩個元素和交換的兩個元素是不同的。
*/public
static
void
shellsort(int data) else
}//右陣列空,左陣列未空
while (left<=leftend)
//左陣列空,右陣列未空
while (rightstar<=right)
//將排序結果拷貝回原來的陣列
for (int i = 0; i < len; i++,right--)
}
基本思想是:1)先從數列中取出乙個數作為基準數;2)分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊;3)再對左右區間重複第二步,直到各區間只有乙個數。
參考:白話經典演算法系列之六 快速排序 快速搞定
白話經典演算法系列之七 堆與堆排序
資料結構整理
常見資料結構 陣列 一對一 棧佇列 鍊錶樹 一對多 圖 多對多 堆雜湊 資料結構是指相互之間存在著一種或多種關係的資料元素的集合和該集合中資料元素之間的關係組成 常用的資料結構有 陣列,棧,鍊錶,佇列,樹,圖,堆,雜湊表等,一.陣列 優點 1 按照索引查詢元素速度快 2 按照索引遍歷陣列方便 缺點 ...
面試集錦(六)資料結構(2)
二叉樹面試 資料結構 資料域 左子節點指標 右子節點指標 遍歷 前序遍歷,中序遍歷,後續遍歷 使用遞迴,結束條件為根節點為空,只是遞迴的順序不同 層次遍歷 分層遍歷二叉樹 按層次從上到下,從左到右 迭代,相當於廣度優先搜尋,使用佇列實現。佇列初始化,將根節點壓入佇列。當佇列不為空,進行如下操作 彈出...
面試 資料結構
先給出定義部分和相關除錯部分 include h using namespace std struct listnode head listnode insert int v while p next null p p next p next new listnode p p next p next...