此次實踐是針對三種查找算法的練習
具體要求:給定關鍵字順序11,78,10,1,3,2,4,21,試分別用順序查找、折半查找、散列查找(用探查法和鏈地址法)來實現查找。試畫出他們的對應存儲形式(順序查找的順序表,二分查找的順序表,兩種散列查找的順序表),並求出每一種找的成功平均查找長度。其中,散列函數H(k)=k%11。算法
因爲有些操做沒法在博客園中顯示,因此我在word文件中作了而後截圖過來。word文件連接數組
順序查找的順序表
因爲順序查找的方法是從第一個開始進行依稀與被查找對象進行比較。因此從頭開始查找每一個元素所須要的次數依次爲。
11:1
78:2
10:3
1:4
3:5
2:6
4:7
21:8
總共進行的查找次數爲1+2+3+4+5+6+7+8=36(次)
查找每一個元素的機率爲:1/8
因此順序查找的平均查找長度爲ASL=36×1/11=9/2函數
二分查找
二分查找的順序表
因爲二分查找首先要進行排序因此的獲得的順序表應該是一個排好序的列表而後進行查找,按照原理首先應該是先比較列表中間的元素。
這個樹狀圖中的數字表示順序表中對應的索引每一層的層數則表示查找次數
這是二分查找對應的代碼3d
public static <T extends Comparable<T>> boolean binarySearch(T[] data, int min, int max, T target) { boolean found = false; int midpoint = (min + max) / 2; // 肯定中點值 if (data[midpoint].compareTo(target) == 0) found = true; else if (data[midpoint].compareTo(target) > 0) { if (min <= midpoint - 1) found = binarySearch(data, min, midpoint - 1, target); } else if (midpoint + 1 <= max) found = binarySearch(data, midpoint + 1, max, target); return found; } }
因爲指針是由最大值和最小值的和,即mid=min+max來決定的,根據代碼是沒法正常運行的,可是當指針不是整數時能夠選擇向左偏。
以數字1爲例進行講解
第一個進行比較的元素是第四個元素,也就是數字4。
第二步:數字1比4小因此將數字1和4 左邊的數字的中間元素進行比較,即與數字2進行比較。
第三步:將1與數字1進行比較。找到數字1。
結合步驟分析與樹形圖的分析獲得。
依此分析,每一個元素被找到所須要進行的查找次數爲
1:3次
2:2次
3:3次
4:1次
10:3次
11:2次
21:3次
78:4次
總共要進行的查找步數爲
1+2×2+3×4+4=21
每一個元素被查找的機率爲1/8
二分查找的ASL=21×1/11=21/8.指針
散列查找的兩種方法分析
由於散列查找須要藉助Hash函數,因此在肯定順序表時也要藉助Hash函數
H(k)=k%11;
給定的元素爲11,78,10,1,3,2,4,21
11%11=0
78%11=1
10%11=10
1%11=1
2%11=2
3%11=3
4%11=4
21%11=10;
線性搜查
思路,先按照取餘獲得的值進行插入,而後若是後面的值進行取餘與前面的衝突,就將後面的值的餘數加一再次進行取餘,直到能夠插入爲之。
用公式來表示大概就是
key,key1表示插入的索引位置
H(k)=k%11=key;
H(k1)=k1%11=key1;
While(num[key1]!=null)
key1=H(key1+1)
按照此原理11應該被插入到0處,78被插到1處,10被插到10處,
由於1%11=1與78衝突,因此應該(1+1)%11=2,將1插入2處,
2%11=2,與1衝突,因此(2+1)%11=3,將2插入3處
3%11=3與2衝突,因此(3+1)%11=4,將3插入4處
4%11=4與3衝突,因此(4+1)%11=5,將4插入5處
21%11=10與10衝突,因此(10+1)%11=0與11衝突,因此(0+1)%11=1與78衝突,因此(1+1)%11=2與1衝突,因此(2+1)%11=3與2衝突,因此(3+1)%11=4與3衝突,因此(4+1)%11=5與5衝突因此將21插入6處。
這樣就能夠獲得
在進行查找時也是按照Hash函數,若是找不到就將餘數加一再模11直至找到爲止
查找過程展現code
被查找元素 | 查找過程 | 查找次數 |
---|---|---|
11 | 11%11=0;int[0]=11查找成功 | 1 |
78 | 78%11=1;int[1]=78查找成功; | 1 |
10 | 10%11=10;int[10]=10,查找成功; | 1 |
1 | 1%11=1;(int[1]=78≠11),(1+1)%11=2 :int[2]=1查找成功; | 2 |
3 | 3%11=3,(int[3] ≠3),(3+1)%11=4,int[4]=3,查找成功; | 2 |
2 | 2%11=2,(int[2] ≠2),(2+1)%11=3,int[3]=2,查找成功; | 2 |
4 | 4%11=4(int[4] ≠4),(4+1)%11=5,int[5]=4,查找成功; | 2 |
21 | 21%11=10(int[10] ≠21),(10+1)%11=0,int[0] ≠21,(0+1)%11=1,int[1] ≠2(1+1)%11=2int[2] ≠21,(2+1)%11=3,int[3] ≠21,(3+1)%11=4,int[4] ≠21,(4+1)%11=5,int[5] ≠21,(5+1)%11=6,int[6]=21,查找成功。 | 8 |
總共查找次數1+1+1+2+2+2+2+8=19
每一個元素被查找的機率爲1/8
線性搜查的ASL=19×1/8=19/8對象
鏈地址法
就是將發生衝突的元素放入同一個鏈表中。創建順序表的方法也是利用Hash函數。
給定的元素
11,78,10,1,3,2,4,21
好比78%11=1,應該插入數組的1處,可是1%11=1,就插入78所在的鏈表中。用圖示來表示就是
blog
這時各元素的查找過程爲,設各索引對應的頭指針爲T1,T2……
11:11%11=0 T0=11,查找成功
78:78%11=1 T1=78,查找成功
10:10%11=10 T10=10,查找成功
1:1%11=1 T1≠1,T1.next=1,查找成功
3:3%11=3 T3=3,查找成功
2:2%11=2 T2=2,查找成功
4:4%11=4 T4=4,查找成功
21:21%11=10 T10≠21, T10.next=21 查找成功
總共進行的查找次數爲
1+1+1+2+1+1+1+2=10
每一個元素被查找到的機率
1/8
ASL=10×1/8=5/4排序