資料結構Java版的查詢演算法實現
阿新 • • 發佈:2019-02-03
import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.Set; /** * 查詢的基本演算法: * - 順下查詢 * -基於線性表的查詢(靜態查詢)- 折半查詢 * - - 分塊查詢 * - * 比較式查詢 - * - - 二叉排序樹(B樹) * - - 平衡二叉樹 * -基於樹的查詢(動態查詢) * - - B- 樹 * - - B+ 樹 * 計算式查詢 - - - - - - - Hash查詢 * * 2017/8/8. */ public class SearchMethod { public static void main(String[] agrs){ int[] num = new int[]{7,9,10,8,2,1,3,4,6,5,20,25,56,0,13,14,15}; // System.out.println(OrderSearch(num,2)); // System.out.println(BinarSearch(num,2)); // int index = BlockSearch(num,SplitBlock(num,3),0); // System.out.println(index); //構建二叉排序樹 // BinarySortTree b = new BinarySortTree(); // b.val = 5; // b.left_child = new BinarySortTree(); // b.right_child = new BinarySortTree(); // b.left_child.val = 3; // b.right_child.val = 7; // b.left_child.left_child = new BinarySortTree(); // b.left_child.right_child = new BinarySortTree(); // b.left_child.left_child.val = 2; // b.left_child.right_child.val = 4; // b.right_child.left_child = new BinarySortTree(); // b.right_child.right_child = new BinarySortTree(); // b.right_child.left_child.val = 6; // b.right_child.right_child.val = 8; // SearchMethod search = new SearchMethod(); // System.out.println(search.BinaryTreeSearch(b,9)); } /** 1 * 順序查詢:逐個比較,直到找到或者查詢失敗。 * 時間複雜度可以表示O(h)=O(n) * 空間複雜度:S(n) = O(n) * @param num 查詢的陣列 * @param n 查詢的數 * @return 返回下標 */ public static int OrderSearch(int[] num,int n){ for (int i = 0; i < num.length - 1; i++) { if (num[i] == n){ return i; } } return -1; } /** 2 * 二分法查詢:對於已經按照一定順序排列好的列表, * 每次都用關鍵字和中間的元素對比,然後判斷是在前部分還是後部分還是就是中間的元素, * 然後繼續用關鍵字和中間的元素對比。 * 時間複雜度可以表示O(h)=O(log2n) * @param num 查詢的陣列 * @param n 查詢的數 * @return 返回下標 */ public static int BinarSearch(int[] num,int n){ int low = 0; int high = num.length - 1; while (low <= high){ int mid = (low+high)/2; int tem = num[mid]; if (tem < n){ low = mid + 1; }else if (tem > n){ high = mid - 1; }else { return mid; } } return -1; } /** * 分塊查詢的分塊:0<可分塊<=查詢陣列元素和 * 採用Hashmap儲存區塊的極值和起始下標 * @param num 查詢陣列 * @param n 分塊個數 * @return 返回分塊起始下標和塊的最大值 */ public static HashMap<Integer,Integer> SplitBlock(int[] num,int n){ HashMap<Integer,Integer> block = new HashMap<>(); int tem = num[0]; for (int i = 0; i < num.length - 1; i++) { if (i % n == 0){ //起始分塊 if ((i+n) >= num.length-1){ //判斷是否是最後一個區塊 最後一個區塊元素可能小於或大於前面區塊元素 for (int j = i; j < num.length; j++) { //區塊內查詢極值 if (num[j] > tem){ tem = num[j]; } } //儲存區塊極值和起始下標 block.put(tem,i); }else { for (int j = i; j < i+n; j++) { //區塊內查詢極值 if (num[j] > tem){ tem = num[j]; } } //儲存區塊極值和起始下標 block.put(tem,i); //初始化區塊比較值 tem = num[i+n-1]; } } } return block; } /** * 分塊查詢:可查詢任意無排序的陣列 * step1 先選取各塊中的最大關鍵字構成一個索引表 * step2 查詢分兩個部分:先對索引表進行二分查詢或 順序查詢,然後在確定的塊中順序查詢。 * ASLbs=(n/s+s)/2 +1,(其中s是每塊的元素個數,n為表長) * 時間複雜度為O(n)~O(log2n) * @param num * @param index * @param n * @return */ public static int BlockSearch(int[] num,HashMap<Integer,Integer> index,int n){ //獲取索引極值進行排序 Iterator<Integer> ite = index.keySet().iterator(); int[] index1 = new int[index.size()]; int i = 0; while (ite.hasNext()){ index1[i++] = ite.next(); } //索引極值從小到大排序 Arrays.sort(index1); //查詢元素所在區塊 for (int j = 0; j < index1.length; j++) { if (n <= index1[j]){ //小於索引值說明在此區塊內進行查詢 int start = index.get(index1[j]); int end = 0; if (j != index1.length -1){ end = index.get(index1[j+1]); }else { end = num.length; } //查詢區塊元素位置 for (int k = start; k < end; k++) { if (n == num[k]){ return k; } } } } return -1; } /** * 二叉排序樹/B樹查詢 * 時間複雜度:O(logn) * @param b 二叉排序樹 * @param n 查詢值 * @return 返回結果 */ public int BinaryTreeSearch(BinarySortTree b,int n){ if (b != null){ if (b.val == n){ return 1; }else if (b.val > n){ return BinaryTreeSearch(b.left_child,n); }else if (b.val < n){ return BinaryTreeSearch(b.right_child,n); } } return -1; } //平衡二叉樹:且具有以下性質:它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。 //最小二叉平衡樹的節點的公式如下 F(n)=F(n-1)+F(n-2)+1 //查詢與二叉排序樹一樣 }