java 二分查詢法和順序查詢法的效率比較
阿新 • • 發佈:2019-01-03
專案背景:
從一個檔案獲取10萬筆字串型別資料,資料庫表中查詢出符合條件的5千數字符竄型別資料。把兩者匹配的資料查詢出來。
結論:
1、如果數量級不大,二種方式速度差不多
2、如果數量級較大
*如果源資料是有序的,則二分查詢法效率高
*如果源資料是無序的,則順序查詢法效率高
原因:
1、字串排序非常耗時
2、二分查詢法需要先排序
執行結果
----------------根據順序查詢法查詢數字-----start 構建的源陣列長度為:10000 從源陣列中隨機抽取500個構建第二個陣列 總共找到的數字個數為:500 總耗時為:14毫秒 end ----------------先對整形陣列進行排序,根據二分查詢法查詢-----start 構建的源陣列長度為:10000 從源陣列中隨機抽取500個構建第二個陣列 10000個數字排序耗時:188毫秒 總共找到的數字的個數為:500 總耗時為:189毫秒 end ----------------根據順序查詢法查詢字元竄-----start 構建的源陣列長度為:10000 從源陣列中隨機抽取500個構建第二個陣列 總共找到的字元竄的個數為:500 總耗時為:42毫秒 end ----------------先對字串陣列進行排序,根據二分查詢法查詢字元竄-----start 構建的源陣列長度為:10000 從源陣列中隨機抽取500個構建第二個陣列 10000個字串排序耗時:1021 總共找到的字元竄的個數為:500 總耗時為:1021毫秒 end
原始碼
package test; import java.util.Random; import java.util.UUID; public class A { /** * @param 順序查詢法、二分查詢法的比較結論 * 1、如果數量級不大,二種方式速度差不多 * 2、如果數量級較大 * *如果源資料是有序的,則二分查詢法效率高 * *如果源資料是無序的,則順序查詢法效率高 */ public static void main(String[] args) throws Exception { testIntArr2(10000, 500); testIntArr1(10000, 500); testStringArr2(10000, 500); testStringArr1(10000, 500); } /** * 整形:使用順序查詢法搜尋陣列 * @param oldLength * @param newLength * @throws Exception */ public static void testIntArr2(int oldLength,int newLength) throws Exception{ System.out.println("----------------根據順序查詢法查詢數字-----start"); int[] arr1 = createIntArr(oldLength);//生成一個包含oldLength個字串的陣列 int[] arr2 = getIntArrFromOtherArr(arr1,newLength);//從陣列中挑選newLength個字串組成第二個陣列 long t0=(long) System.currentTimeMillis();//開始計時 int searchedNum=0; for(int i=0;i<arr2.length;i++){ int temp = arr2[i]; for(int j=0;j<arr1.length;j++){ if(temp==arr1[j]){ searchedNum++; continue; } } } System.out.println("總共找到的數字個數為:"+searchedNum); long t1=(long) System.currentTimeMillis(); System.out.println("總耗時為:"+(t1-t0)+"毫秒"); System.out.println("end"); } /** * 整形:使用二分查詢法搜尋陣列 * @param oldLength * @param newLength * @throws Exception */ public static void testIntArr1(int oldLength,int newLength) throws Exception{ System.out.println("----------------先對整形陣列進行排序,根據二分查詢法查詢-----start"); int[] arr1 = createIntArr(oldLength);//生成一個包含oldLength的陣列 int[] arr2 = getIntArrFromOtherArr(arr1,newLength);//從陣列中挑選newLength個組成第二個陣列 long t0=(long) System.currentTimeMillis();//開始計時 sort(arr1);//使用氣泡排序法對陣列1排序 long t1=(long) System.currentTimeMillis(); System.out.println(oldLength+"個數字排序耗時:"+(t1-t0)+"毫秒"); int searchedNum = 0; for(int i=0;i<arr2.length;i++){ int temp = arr2[i]; if(binarySearch(arr1, temp)>0){ searchedNum++; } } System.out.println("總共找到的數字的個數為:"+searchedNum); long t2=(long) System.currentTimeMillis(); System.out.println("總耗時為:"+(t2-t0)+"毫秒"); System.out.println("end"); } /** * 字串:使用順序查詢法搜尋陣列 * @param oldLength * @param newLength * @throws Exception */ public static void testStringArr2(int oldLength,int newLength) throws Exception{ System.out.println("----------------根據順序查詢法查詢字元竄-----start"); String[] arr1 = createStringArr(oldLength);//生成一個包含oldLength個字串的陣列 String[] arr2 = getStringArrFromOtherArr(arr1,newLength);//從陣列中挑選newLength個字串組成第二個陣列 long t0=(long) System.currentTimeMillis();//開始計時 int searchedNum=0; for(int i=0;i<arr2.length;i++){ String temp = arr2[i]; for(int j=0;j<arr1.length;j++){ if(temp.equals(arr1[j])){ searchedNum++; continue; } } } System.out.println("總共找到的字元竄的個數為:"+searchedNum); long t1=(long) System.currentTimeMillis(); System.out.println("總耗時為:"+(t1-t0)+"毫秒"); System.out.println("end"); } /** * 字串:使用二分查詢法搜尋陣列 * @param oldLength * @param newLength * @throws Exception */ public static void testStringArr1(int oldLength,int newLength) throws Exception{ System.out.println("----------------先對字串陣列進行排序,根據二分查詢法查詢字元竄-----start"); String[] arr1 = createStringArr(oldLength);//生成一個包含oldLength個字串的陣列 String[] arr2 = getStringArrFromOtherArr(arr1,newLength);//從陣列中挑選newLength個字串組成第二個陣列 long t0=(long) System.currentTimeMillis();//開始計時 sort(arr1);//使用氣泡排序法對陣列1排序 long t1=(long) System.currentTimeMillis(); System.out.println(oldLength+"個字串排序耗時:"+(t1-t0)); int searchedNum = 0; for(int i=0;i<arr2.length;i++){ String temp = arr2[i]; if(binarySearch(arr1, temp)>0){ searchedNum++; } } System.out.println("總共找到的字元竄的個數為:"+searchedNum); long t2=(long) System.currentTimeMillis(); System.out.println("總耗時為:"+(t2-t0)+"毫秒"); System.out.println("end"); } /** *二分查詢法:字元竄 * @param arr * @param num * @return */ public static int binarySearch(String[] arr , String num){ int start =0; int end = arr.length-1; while(start<=end){ int mid = (start+end)/2; if(num.compareTo(arr[mid]) > 0){ start=mid+1; }else if(num.compareTo(arr[mid]) < 0){ end=mid-1; }else{ return mid; } } return -1; } /** * 二分查詢法:整數 * @param arr * @param num * @return */ public static int binarySearch(int[] arr , int num){ int low = 0; int upper=arr.length-1; while(low<=upper){ int mid = (low+upper)/2; if(arr[mid] < num){ low = mid+1; }else if(arr[mid] > num){ upper=mid-1; }else{ return mid; } } return -1; } /** * 字元竄從小到大排序 * @param arr */ public static void sort(String[] arr){ for(int i=0;i<arr.length;i++){ for(int j=0;j<arr.length-i-1;j++){ if(arr[j].compareTo(arr[j+1]) > 0){ String temp = arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } // for(String x : arr){ // System.out.println(x); // } } /** * 整形陣列氣泡排序:從小到大 */ public static void sort(int[] arr){ for(int i=0;i<arr.length;i++){ for(int j=0;j<arr.length-i-1;j++){ if(arr[j]>arr[j+1]){ int temp = arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } // for(int x : arr){ // System.out.println(x); // } } /** * 構建字串陣列---包含num個uuid * @return */ public static String[] createStringArr(int num){ String[] arr = new String[num]; for(int i=0;i<num;i++){ arr[i] = UUID.randomUUID().toString(); } System.out.println("構建的源陣列長度為:"+arr.length); return arr; } /** * 從源陣列中隨機選擇n個數據,構建第二個陣列 * @param source * @return * @throws Exception */ public static String[] getStringArrFromOtherArr(String[] source,int n) throws Exception{ if(n>source.length){ throw new Exception("不能超過源陣列的長度"); } Random random = new Random(); String[] arr = new String[n]; for(int i=0;i<n;i++){ int index = random.nextInt(source.length-1); arr[i]=source[index]; } System.out.println("從源陣列中隨機抽取"+arr.length+"個構建第二個陣列"); return arr; } /** * 構建整形陣列---包含num個整形 * @return */ public static int[] createIntArr(int num){ Random random = new Random(); int[] arr = new int[num]; for(int i=0;i<num;i++){ arr[i] = random.nextInt(); } System.out.println("構建的源陣列長度為:"+arr.length); return arr; } /** * 從源陣列中隨機選擇n個數據,構建第二個陣列 * @param source * @return * @throws Exception */ public static int[] getIntArrFromOtherArr(int[] source,int n) throws Exception{ if(n>source.length){ throw new Exception("不能超過源陣列的長度"); } Random random = new Random(); int[] arr = new int[n]; for(int i=0;i<n;i++){ int index = random.nextInt(source.length-1); arr[i]=source[index]; } System.out.println("從源陣列中隨機抽取"+arr.length+"個構建第二個陣列"); return arr; } }