一、順序無序查找算法
順序查找算法很簡單也很好理解,就是在一個序列中從前往后遍歷集合直到查到目標值為止。通常查找最大值和最小值都是這種方法。
1、順序查找的一般實現:
public static int SqSearch(int[] source, int target) { for (int i = 0; i < source.Length; i++) { if (source[i] == target) { return i; } } return -1; }
查找最大值
public static int FindMax(int[] source) { int max=source[0]; for(int i=1;i<source.Length;i++){ if(max<source[i]){ max=source[i]; } } return max; }
查找最小值
public static int FindMin(int[] source) { int min = source[0]; for (int i = 1; i < source.Length; i++) { if (source[i] < min) { min = source[i]; } } return min; }
順序查找的特點是查找效率依賴於元素所在的位置,如果查找元素在第一個,那就是秒查,效率非常高,如果查詢元素在最后一個那么就要遍歷整個集合,效率就低了。
改變集合數據加快查詢效率
根據“2-8”定律,一般情況下20%的數據是hot data, 80%是cool data, 數據也符合現在的財富“2-8 ”定律,因此在查詢數據的時候可以將每次查到的數據移動到頭部的20%,這樣就會將hot data 放在最前面這樣就可以提高效率。
public static int Hot20SqSearch(int[] source, int target) { for (int i = 0; i < source.Length; i++) { if (source[i] == target) { if (i > source.Length * 0.2) { var temp = source[0]; source[0] = source[i]; source[i] = temp; } return i; } } return -1; }
這樣會解決部分問題,但是還是有問題,如果每次都查的是頭部20%的數據沒有問題,但是如果查到一個后面的80%的數據,就會將第一個hot data交換到后面的的位置了,下次查詢就又慢了的問題,還有一種方式就是每次查到的詞只向前移動一個位置,如果是高頻詞查的多了必然會跑到最前面,下面是這種改變查詢結果的代碼:
public static int HotSwapSqSearch(int[] source, int target) { for (int i = 0; i < source.Length; i++) { if (source[i] == target) { if (i > 0) { var temp = source[i-1]; source[i-1] = source[i]; source[i] = temp; } return i; } } return -1; }
現在手機上的中文輸入法,就會就和這個類似,讓輸入的高頻詞放在輸入法的最前面方便輸入文字。
二、二叉查找算法
二叉查找算法是基於有序序列的一種查找算法,上面的順序查找算法是無序的。二叉查找的特點是每次通過和中間值的比較來決定是查找中間值左邊部分,還是查詢右邊部分。和電視上的猜商品的價格游戲是一樣的,根據“一半”的策略縮小范圍,最終猜到商品的價格,下面是典型的代碼:
public static int BinSearch(int[] source, int target) { int left = 0, right = source.Length-1,middle; while (left <= right) { middle = (left + right) / 2; if (source[middle] == target) { return middle; } else { if (source[middle] > target) { right = middle - 1; } else { left = middle + 1; } } } return -1; }
三、遞歸實現二叉算法
二叉查找每次都是給定一個集合並給定一個最小索引和最大索引,不斷的縮小集合的大小,進而縮小查找范圍,直至查到或者集合中沒有元素了。因此這也是一個標准的遞歸算法,用遞歸實現二叉查找:
public static int RBinSearch(int[] source, int target, int left, int right) { if (left > right) { return -1; } else { int middle = (int)(left + right) / 2; if (source[middle] == target) { return middle; } else { if (source[middle] > target) { return RBinSearch(source, target, left, right - 1); } else { return RBinSearch(source, target, left + 1, right); } } } }
這幾個基礎的查找算法,在平時開發的過程中經常會用到。現在的框架做的事情太多了,像這些基礎的算法,可能只有在學校或者考試的時候才能用上,但是這些都是基礎,只有掌握了這些基礎知識才能更好的使用框架或者類庫提供的方法。