查找算法:順序查找、二分查找、分塊查找、二叉查找樹、B樹、B+樹java
1、二分查找(常規)算法
題目描述:數組
(牛客網http://www.nowcoder.com/practice/28d5a9b7fc0b4a078c9a6d59830fb9b9?rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking)測試
對於一個有序數組,咱們一般採用二分查找的方式來定位某一元素,請編寫二分查找的算法,在數組中查找指定元素。spa
給定一個整數數組A及它的大小n,同時給定要查找的元素val,請返回它在數組中的位置(從0開始),若不存在該元素,返回-1。若該元素出現屢次,請返回第一次出現的位置。3d
測試樣例:code
[1,3,5,7,9],5,3
返回:1
public class BinarySearch { public int getPos(int[] A, int n, int val) { // write code here //遞歸實現 //return binarySearch(A, val, n, 0); //非遞歸實現 return binarySearch2(A, val, n); } //遞歸實現 public int binarySearch(int[] pA, int pval, int high, int low){ int mid = (high+low)/2;//相加 if(low>high){ return -1; } if(pA[mid]==pval){ while(mid>0 && pA[mid-1]==pval){ mid--; } return mid; }else if(pA[mid]>pval){//中間值大於pval return binarySearch(pA, pval, mid-1, low); }else{//中間值小於pval return binarySearch(pA, pval, high, mid+1); } } //非遞歸實現 public int binarySearch2(int[] pA, int pval, int n){ int high=n, low=0, mid; while(low<=high){ mid = (high+low)/2; if(pA[mid]==pval){ while(mid>0 && pA[mid-1]==pval){ mid--; } return mid; }else if(pA[mid]>pval){ high = mid-1; }else{ low = mid+1; } } return -1; } }
2、二分查找變形題排序
一、查找旋轉數組中最小值遞歸
題目描述:get
(牛客網http://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking)
把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉。
輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
NOTE:給出的全部元素都大於0,若數組大小爲0,請返回0。
public class Solution { public int minNumberInRotateArray(int [] array) { if(array.length==0){ return 0; }else{ return binarySearch(array); } } //兩種狀況: //狀況1:嚴格遞增 第一個值老是大於最後一個值 //尋找中間值,若中間值大於第一個值,則最小值位於中間值右側 //反之若中間值小於第一個值,則最小值位於中間值及中間值左側 //狀況2:非遞減(順序查找,只須要查找後一個比前一個小即爲最小值,若沒有查到則返回第一個數據) public int binarySearch(int[] parray){ int n=parray.length; int left=0, right=n-1, mid; while(left<=right){ mid = (right+left)/2; //狀況2 if(parray[mid]==parray[left] && parray[mid]==parray[right]){ boolean flag=false; for(int i=1; i<n; i++){ if(parray[i]<parray[i-1]){ flag = true; return parray[i]; } } if(flag==false){ return parray[0]; } } //狀況1 if(parray[mid]>parray[left]){//中間值大於第一個值 left = mid+1; }else{//中間值小於第一個值 right = mid;//最小值可能恰好是中間值 } } return parray[right]; } }
有興趣的能夠看看詳細分析:
參考網址:http://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba
3、二叉查找樹
一、題目描述(很經典)
(牛客網http://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176)
輸入一個整數數組,判斷該數組是否是某二叉搜索樹的後序遍歷的結果。若是是則輸出Yes,不然輸出No。假設輸入的數組的任意兩個數字都互不相同。
public class Solution { public boolean VerifySquenceOfBST(int [] sequence) { if(sequence.length==0){//數組爲空的時候 return false; }else{ return PostOrderTraversal(sequence, 0, sequence.length-1); } } public boolean PostOrderTraversal(int[] data, int low, int high) { if(low >= high) { return true; } int split = -1; int i; boolean found = false; //to see if the data can be splited as ABC where c is the last one, all members in A < c, B > c for( i = low; i < high; i++) { if(data[i] > data[high] ) { if(split == -1) { split = i; found = true; } } if(data[i] < data[high] && split != -1) { return false; } } if(! found )//only A < c or B > c; { return PostOrderTraversal(data, low, high-1); } else //recursive way { return PostOrderTraversal(data, low, split - 1) && PostOrderTraversal(data, split, high-1); } } }
以上爲遞歸算法,固然也有非遞歸。
今天就寫到這,以後再慢慢累積更新。