Introduction to search algorithm
In java, there are four common Searches:
1. Sequential (linear) search
2. Binary search / half search
3. Interpolation search
4. Fibonacci search
Linear search
There is a sequence: {1,8,10,8910001234}. Judge whether the sequence contains this name [sequential search]
Requirement: if it is found, it will prompt that it is found, and give the subscript value
Code implementation:
package search; /** * Linear search */ public class SeqSearch { public static void main(String[] args) { int arr[] = {1,9,11,-1,34,89};//Array without order int index = seqSearch(arr,11); if (index == -1){ System.out.println("Can't find"); }else { System.out.println("find,Subscript is="+index); } } /** * Here, we implement linear search to find a value that meets the conditions and return it * @param arr * @param value * @return */ public static int seqSearch(int[] arr ,int value){ //Linear search is to compare one by one. If the same value is found, the subscript is returned for (int i = 0; i < arr.length; i++){ if (arr[i] == value){ return i; } } return -1; } }
Binary search algorithm
Binary search:
Please perform a binary search {1,8,10,8910001234} on an ordered array, enter a number to see if this number exists in the array, and find the subscript. If not, you will be prompted "there is no such number"
Thinking: {1,8,10,8910001234} when there are multiple identical values in an ordered array, how to find all the values, such as 1000 here
Train of thought analysis
Code implementation:
Note: the subscript of finding all elements that meet the conditions is added:
package search; import com.sun.source.tree.NewArrayTree; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; /** * Binary search * Note: arrays must be ordered */ public class BinarySearch { public static void main(String[] args) { int arr[] = {1, 8, 10, 1000,1000,1000, 1234}; // int resIndex = binarySearch(arr,0,arr.length - 1,1); // System.out.println("resIndex="+resIndex); List<Integer> restIndexList =binarySearch2(arr,0,arr.length-1,1000); System.out.println(restIndexList); } //Binary search algorithm /** * @param arr array * @param left Index on the left * @param right Index on the right * @param findVal Value to find * @return If it is found, it returns the subscript. If it is not found, it returns - 1 */ public static int binarySearch(int[] arr, int left, int right, int findVal) { //When left > right, it means that the whole array is recursive, but it is not found if (left > right){ return -1; } int mid = (left + right) / 2; int midVal = arr[mid]; if (findVal > midVal) { //Recursive right return binarySearch(arr, mid + 1, right, findVal); } else if (findVal < midVal) {// Left recursion return binarySearch(arr, left, mid - 1, findVal); } else { return mid; } } //Complete thinking /* {1,8,10,89,1000,1000,1234}When in an ordered array, How to find all the values when there are multiple identical values, such as 1000 Train of thought analysis 1:Do not return the mid index value immediately after it is found 2:Scan to the left of the mid index value, and add all element subscripts that meet 1000 to the set ArrayList 3:Scan to the right of the mid index value, and add all element subscripts that meet 1000 to the set ArrayList 4:Return ArrayList to */ public static ArrayList binarySearch2(int[] arr, int left, int right, int findVal) { //When left > right, it means that the whole array is recursive, but it is not found if (left > right){ return new ArrayList<Integer>(); } int mid = (left + right) / 2; int midVal = arr[mid]; if (findVal > midVal) { //Recursive right return binarySearch2(arr, mid + 1, right, findVal); } else if (findVal < midVal) {// Left recursion return binarySearch2(arr, left, mid - 1, findVal); } else { /* 1:Do not return the mid index value immediately after it is found 2:Scan to the left of the mid index value, and add all element subscripts that meet 1000 to the set ArrayList 3:Scan to the right of the mid index value, and add all element subscripts that meet 1000 to the set ArrayList 4:Return ArrayList to */ ArrayList<Integer> resIndexList = new ArrayList<Integer>(); int temp = mid - 1; while (true){ if (temp < 0 || arr[temp] != findVal){ //sign out break; } //Otherwise, it is temp and put into reindexlist resIndexList.add(temp); temp -=1; } resIndexList.add(mid); //Scan to the right of the mid index value, and add all element subscripts that meet 1000 to the set ArrayList temp = mid + 1; while (true){ if (temp > arr.length-1 || arr[temp] != findVal){ //sign out break; } //Otherwise, you can use temp and put it into reindexlist resIndexList.add(temp); temp +=1; } return resIndexList; } } }
Interpolation lookup
Introduction to interpolation search principle:
(1) The interpolation search algorithm is similar to binary search, except that the interpolation search starts from the adaptive mid every time
(2) The formula for finding mid index in half search. low represents the left index and high represents the right index
key is our findVal
(3)int midindex = low +(high - low) *(key - arr[low]) / (arr[high] -arr[low]; / * interpolation index*/
Corresponding to the previous code formula:
int mid = left + (right - left) * (findVal -arr [left]) / (arr[right] - arr[left])
(4) An example is given to illustrate the array of interpolation search algorithm 1-100
Interpolation search application case:
Please find an ordered array, find {1,8,10,8910001234}, enter a number to see if the number exists, and write out the subscript. If not, you will be prompted with "no such number"
Code implementation:
package search; /** * Interpolation lookup */ public class InsertValueSearch { public static void main(String[] args) { int [] arr = new int[100]; for (int i = 0; i <100 ;i++){ arr[i] = i + 1; } int index =insertValueSearch(arr,0,arr.length-1,100); System.out.println("index="+index); } //Write interpolation search algorithm //Interpolation search algorithm also requires an orderly array /** * * @param arr array * @param left Left index * @param right Right index * @param findVal Find value * @return */ public static int insertValueSearch(int[] arr, int left, int right, int findVal){ //Note: findval < arr [0] and arr[arr.length-1] must be required //Otherwise, the mid we get may cross the border if (left > right || findVal < arr[0] || findVal >arr[arr.length-1]){ return -1; } //Find the mid, adaptive int mid = left + (right -left) *(findVal -arr[left]) / (arr[right] - arr[left]); int midVal =arr[mid]; if(findVal > midVal) {// Description should recurse to the right return insertValueSearch(arr, mid + 1, right, findVal); }else if (findVal < midVal) {//Description should look recursively to the left return insertValueSearch(arr, mid - 1, right, findVal); }else { return mid; } } }
Precautions for interpolation search:
(1) For the lookup table with large amount of data and uniform keyword distribution, interpolation is faster
(2) The keyword distribution is uneven, and this method is not necessarily better than half search
Fibonacci (golden section) search algorithm
Fibonacci (golden section) search basic introduction:
(1) : the golden section point refers to dividing a line segment into two parts, so that the ratio of one part to the whole length is equal to the ratio of the other part to this part. The approximate value of the first three digits is 0.618. Therefore, the shape designed according to this ratio is very beautiful, so it is called the golden section, also known as the middle to outer ratio. This is a magical number, which will bring unexpected effects
(2) Fibonacci sequence {1,1,2,3,4,5,13,21,34,55} it is found that the ratio of two adjacent numbers of Fibonacci sequence is infinitely close to the golden section value of 0.618
Fibonacci principle:
The Fibonacci search principle is similar to the first two, only changing the position of the intermediate node (mid). The mid is not only obtained by intermediate or interpolation, but is located near the golden section point, that is, mid=low+F(k-1)-1 (F represents Fibonacci sequence), as shown in the figure below
Understanding of F(k-1)-1:
(1) Due to the property of Fibonacci sequence F[k]=F[k-1]+F[k-2], it can be obtained that (F[k-1]) = (F[k-1]-1) + (F[k-2]-1)+1
The formula shows that as long as the length bit F[k]-1 of the sequence table, the table can be divided into two segments of growth bit F[k-1]-1 and F[k-2]-1,
That is, as shown in the above figure, from the middle position bit mid=low+F(k-1)-1
(2) Similarly, each sub segment can be divided in the same way
(3) However, the length n of the sequence table is not necessarily equal to F[k-1], so it is necessary to increase the length n of the original sequence table to F[k]-1. The value of K here can be obtained from the following code as long as F[k-]1 is exactly equal to or greater than N. after the length of the sequence table increases, the new position (from n+1 to F[k]-1 position) can be assigned as the value of N position
Fibonacci find application case:
Please perform Fibonacci search {1,8,10,8910001234} on an ordered array, enter a number to see if the array exists at this time, and find the subscript. If not, you will be prompted "there is no such number"
Code implementation:
package search; import java.util.Arrays; /** * fibonacci search * Note: ordered array */ public class FibonacciSearch { public static int maxSize = 20; public static void main(String[] args) { int [] arr ={1,8,10,89,1000,1234}; System.out.println("index="+fibSearch(arr,1234)); } //Since we need to use Fibonacci sequence for mid = low+f(k-1)-1, we need to obtain a Fibonacci sequence first //A Fibonacci sequence is obtained in a non recursive way public static int[] fib(){ int[] f = new int[maxSize]; f[0] = 1; f[1] = 1; for (int i = 2; i < maxSize; i++){ f[i] = f[i - 1] + f[i-2]; } return f; } //Write Fibonacci search algorithm //Write the algorithm in a non recursive way /** * * @param a array * @param key Key (value) we need to find * @return Returns the subscript for, if not - 1 */ public static int fibSearch(int[]a,int key){ int low = 0; int high = a.length-1; int k = 0; //Subscript representing the Fibonacci division value int mid = 0; //Store mid value int f[] =fib(); //Get Fibonacci sequence //Get the subscript of Fibonacci division value while (high > f[k] -1){ k++; } //Because the f[k] value may be greater than the length of a, we need to use the Arrays class to construct a new array and point to temp [] //The insufficient part is filled with 0 int [] temp = Arrays.copyOf(a,f[k]); //In fact, you need to fill temp with the last number of the a array //give an example: //temp ={1,8,10,89,1000,1234,0,0,0} =>{1,8,10,89,1000,1234,1234,1234,1234} for (int i = high + 1; i <temp.length; i++){ temp[i] = a[high]; } //Use while to cycle and find our number key while(low <= high){ //As long as this condition is met, you can find it mid = low + f[k-1]-1; if (key < temp[mid]){ //We should continue to look in front of the array (left) high = mid -1; /* Why k-- explain: 1.All elements = front elements + rear elements 2.f[k] = f[k-1] + f[k-2] Because there are f[k-1] elements in front, you can continue to split f[k-1] = f[k-1] + f[k-3] That is, continue to find K in front of f[k-1] That is, the next cycle mid=f[k-1-1]-1 */ k--; }else if (key > temp[mid]){ //We should continue to look behind the array (to the right) low = mid + 1; /* Why k -=2 explain 1.All elements = front elements + rear elements 2.f[k] = f[k-1] + f[k-2] 3.Because there are f[k-2] in the back, you can continue to split f[k-1] = f[k-3] + f[k -4] 4.That is, find k -=2 in front of f[k-2] 5.That is, the next cycle mid = f[k-1-2]-1 */ k -=2; }else { //find //You need to make sure that the subscript is returned if (mid <=high){ return mid; }else { return high; } } } return -1; } }