Java偷走了我的微笑
Published on 2017-09-02 11:31 in 暂未分类 with Java投走了我的微笑

常用算法总结

算法面试的准备范围

算法面试的准备范围

排序算法分类

算法的时间复杂度总结

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/1615d852-4da2-4e51-9733-a68bc0de2389.jpg)

常见排序算法

冒泡排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/640.gif)

// Java 代码实现
 public class BubbleSort implements IArraySort {
 
     @Override
     public int[] sort(int[] sourceArray) throws Exception {
         // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
 // 外面循环表示  进行了多少轮  即n-1 次循环
         for (int i = 1; i < arr.length; i++) {
            // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
            boolean flag = true;
                //  每次循环 ,冒泡比较的次数
            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int tmp = arr[j];
                   arr[j] = arr[j + 1];
                   arr[j + 1] = tmp;
                    flag = false;
               }
           }

         if (flag) {
              break;
           }     
         }
      return arr;
    }
}

选择排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/bfb3f6756850a695521201ae7c27b056.gif)

//Java 代码实现
 public class SelectionSort implements IArraySort {
 
    @Override
     public int[] sort(int[] sourceArray) throws Exception {
         int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
 
         // 总共要经过 N-1 轮比较
         for (int i = 0; i < arr.length - 1; i++) {
             // min 为每轮 假设最小值的下标
            int min = i;

            // 每轮需要比较的次数 N-i
             //每轮 都从i的后一个元素开始比较 
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    // 记录目前能找到的最小值元素的索引
                   min = j;
               }
            }

           // 将找到的最小值和i位置所在的值进行交换
           if (i != min) {
               int tmp = arr[i];
               arr[i] = arr[min];
                arr[min] = tmp;
           }

       }
       return arr;
   }
}

插入排序

把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/85113fded8f6c454716288737c2c6bda.gif)

//Java 代码实现
public class InsertSort implements IArraySort {
 。。
     
     
     
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {

            // 记录要插入的数据
            int tmp = arr[i];

            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            //j-1 即带插入元素的前一个元素的下表一定要>=0 ,即j>=1。即j>0 
            while (j > 0 && tmp < arr[j - 1]) {
                // 将j-1 这个位置的元素后移  
                arr[j] = arr[j - 1];
                j--;
            }

            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }

        }
        return arr;
    }
}

希尔排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/a761b5340557f45a1466d5b25a5f9d81.gif)

快速排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/79854b85-6f9d-4600-935b-c0fe8ba07c5f.jpg)

这是采用递归的手段,从数组中 先找到j,把它放到该放的位置,左边小,右边大。 再递归,...

import java.util.*;

public class QuickSort {

    // 对arr[l...r]部分进行partition操作
    // 返回p, 使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]
    private static int partition(int[] arr, int l, int r){

        int v = arr[l];

        int j = l; // arr[l+1...j] < v ; arr[j+1...i) > v
        // i 表示数组中待遍历的元素
        for( int i = l + 1 ; i <= r ; i ++ )
            // 如果arrI 大于 v,不用管,直接在后面+1 即可。 如果小,则要变换位置 。
            if( arr[i] < v){
                j ++;
                swap(arr, j, i);
            }

        swap(arr, l, j);

        return j;
    }

    // 递归使用快速排序,对arr[l...r]的范围进行排序
    private static void sort(int[] arr, int l, int r){

        if( l >= r )
            return;
// 从一堆数组中,找一个元素(第0个),把它放到它该放的位置。返回它的索引
        int p = partition(arr, l, r);
        sort(arr, l, p-1 );
        sort(arr, p+1, r);
    }

 
 
}

归并排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/37f66390f7be010a0aaaefbe05cfa9a7.gif)

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/d5a1d4a3-5d61-4f76-a965-f11e40f8a55f.jpg)

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/9f8aaf97-33ed-4f74-afc7-994868de0951.jpg)

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class MergetSort {

    public static void main(String[] args) {
        int arr[] = { 8, 4, 5, 7, 1, 3, 6, 2 }; //
        
        
        System.out.println("排序前的时间是=" + date1Str);
        
        int temp[] = new int[arr.length]; //归并排序需要一个额外空间
        mergeSort(arr, 0, arr.length - 1, temp);
        
    }
    
    
    //递归使用 归并排序,将arr[left...right]范围进行排序
    public static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if(left < right) {
            int mid = (left + right) / 2; //中间索引
            //向左递归进行分解
            mergeSort(arr, left, mid, temp);
            //向右递归进行分解
            mergeSort(arr, mid + 1, right, temp);
            // 此时 ,假设分解成了2部分, 左边一半 有序, 右边一半有序,再进行合并操作
            //合并
            merge(arr, left, mid, right, temp);
            
        }
    }
    
    //合并的方法
    /**
     * 
     * @param arr 排序的原始数组
     * @param left 左边有序序列的初始索引
     * @param mid 中间索引
     * @param right 右边索引
     * @param temp 做中转的数组
     */
    public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        
        int i = left; // 初始化i, 左边有序序列的初始索引
        int j = mid + 1; //初始化j, 右边有序序列的初始索引
        int t = 0; // 指向temp数组的当前索引
        
        //(一)
        //先把左右两边(有序)的数据按照规则填充到temp数组
        //直到左右两边的有序序列,有一边处理完毕为止
        while (i <= mid && j <= right) {//继续
            //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
            //即将左边的当前元素,填充到 temp数组 
            //然后 t++, i++
            if(arr[i] <= arr[j]) {
                temp[t] = arr[i];
                t += 1;
                i += 1;
            } else { //反之,将右边有序序列的当前元素,填充到temp数组
                temp[t] = arr[j];
                t += 1;
                j += 1;
            }
        }
        
        //(二)
        //把有剩余数据的一边的数据依次全部填充到temp
        while( i <= mid) { //左边的有序序列还有剩余的元素,就全部填充到temp
            temp[t] = arr[i];
            t += 1;
            i += 1; 
        }
        
        while( j <= right) { //右边的有序序列还有剩余的元素,就全部填充到temp
            temp[t] = arr[j];
            t += 1;
            j += 1; 
        }
        
        
        //(三)
        //将temp数组的元素拷贝到arr
        
        t = 0;
        int tempLeft = left; // 

        while(tempLeft <= right) { 
            arr[tempLeft] = temp[t];
            t += 1;
            tempLeft += 1;
        }
        
    }

}

排序算法对比

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/a1d80208-81dc-4dff-a5ed-b7eee560c347.png)

常见查找算法

线性查找

low的一匹,就是根据所以,一个一个去对比

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/eb2f40da-b5a2-4aed-86e6-a381d514578b.png)

二分查找及其改进

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/78a54b8c-0428-47ae-a472-13371eb269e9.jpg)

改进,比如 {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中, 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000

//注意:使用二分查找的前提是 该数组是有序的.
public class BinarySearch {

    public static void main(String[] args) {
        int arr[] = {1, 8, 10, 89, 1000, 1000, 1234};
         int resIndex = binarySearch(arr, 0, arr.length - 1, 2);
        System.out.println("resIndex=" + resIndex);
    }
 
    // 二分查找算法
   /**
     * @param arr     数组
     * @param left    左边的索引
     * @param right   右边的索引
     * @param findVal 要查找的值
     * @return 如果找到就返回下标,如果没有找到,就返回 -1
     */
    public static int binarySearch(int[] arr, int left, int right, int findVal) {

        // 当 left > right 时,说明递归整个数组,但是没有找到
        if (left > right) {
            return -1;
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) { // 向 右递归
            return binarySearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) { // 向左递归
            return binarySearch(arr, left, mid - 1, findVal);
        } else {
            return mid;
        }
   }
    
        //完成一个课后思考题:
    /*
     * 课后思考题: {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中,
     * 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000
     * 
     * 思路分析
     * 1. 在找到mid 索引值,不要马上返回
     * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
     * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
     * 4. 将Arraylist返回
     */

    public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {

        System.out.println("hello~");
        // 当 left > right 时,说明递归整个数组,但是没有找到
        if (left > right) {
            return new ArrayList<Integer>();
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) { // 向 右递归
            return binarySearch2(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) { // 向左递归
            return binarySearch2(arr, left, mid - 1, findVal);
        } else {
//           * 思路分析
//           * 1. 在找到mid 索引值,不要马上返回
//           * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
//           * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
//           * 4. 将Arraylist返回
            
            List<Integer> resIndexlist = new ArrayList<Integer>();
            //向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
            int temp = mid - 1;
            while(true) {
                if (temp < 0 || arr[temp] != findVal) {//退出
                    break;
                }
                //否则,就temp 放入到 resIndexlist
                resIndexlist.add(temp);
                temp -= 1; //temp左移
            }
            resIndexlist.add(mid);  //
            
            //向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
            temp = mid + 1;
            while(true) {
                if (temp > arr.length - 1 || arr[temp] != findVal) {//退出
                    break;
                }
                //否则,就temp 放入到 resIndexlist
                resIndexlist.add(temp);
                temp += 1; //temp右移
            }
            
            return resIndexlist;
        }

    }
    
}

插值查找

斐波那契查找

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/52fcfb31-0ed5-46a2-81c7-7b537a28bda5.jpg)

排序算法分类

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/02c0e500-cc83-4f08-a0fd-583f9a548a40.jpg)

算法的时间复杂度总结

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/1615d852-4da2-4e51-9733-a68bc0de2389.jpg)

常见排序算法

冒泡排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/640.gif)

// Java 代码实现
 public class BubbleSort implements IArraySort {
 
     @Override
     public int[] sort(int[] sourceArray) throws Exception {
         // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
 // 外面循环表示  进行了多少轮  即n-1 次循环
         for (int i = 1; i < arr.length; i++) {
            // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
            boolean flag = true;
                //  每次循环 ,冒泡比较的次数
            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int tmp = arr[j];
                   arr[j] = arr[j + 1];
                   arr[j + 1] = tmp;
                    flag = false;
               }
           }

         if (flag) {
              break;
           }     
         }
      return arr;
    }
}

选择排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/bfb3f6756850a695521201ae7c27b056.gif)

//Java 代码实现
 public class SelectionSort implements IArraySort {
 
    @Override
     public int[] sort(int[] sourceArray) throws Exception {
         int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
 
         // 总共要经过 N-1 轮比较
         for (int i = 0; i < arr.length - 1; i++) {
             // min 为每轮 假设最小值的下标
            int min = i;

            // 每轮需要比较的次数 N-i
             //每轮 都从i的后一个元素开始比较 
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    // 记录目前能找到的最小值元素的索引
                   min = j;
               }
            }

           // 将找到的最小值和i位置所在的值进行交换
           if (i != min) {
               int tmp = arr[i];
               arr[i] = arr[min];
                arr[min] = tmp;
           }

       }
       return arr;
   }
}

插入排序

把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/85113fded8f6c454716288737c2c6bda.gif)

//Java 代码实现
public class InsertSort implements IArraySort {
 。。
     
     
     
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {

            // 记录要插入的数据
            int tmp = arr[i];

            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            //j-1 即带插入元素的前一个元素的下表一定要>=0 ,即j>=1。即j>0 
            while (j > 0 && tmp < arr[j - 1]) {
                // 将j-1 这个位置的元素后移  
                arr[j] = arr[j - 1];
                j--;
            }

            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }

        }
        return arr;
    }
}

希尔排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/a761b5340557f45a1466d5b25a5f9d81.gif)

快速排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/79854b85-6f9d-4600-935b-c0fe8ba07c5f.jpg)

这是采用递归的手段,从数组中 先找到j,把它放到该放的位置,左边小,右边大。 再递归,...

import java.util.*;

public class QuickSort {

    // 对arr[l...r]部分进行partition操作
    // 返回p, 使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]
    private static int partition(int[] arr, int l, int r){

        int v = arr[l];

        int j = l; // arr[l+1...j] < v ; arr[j+1...i) > v
        // i 表示数组中待遍历的元素
        for( int i = l + 1 ; i <= r ; i ++ )
            // 如果arrI 大于 v,不用管,直接在后面+1 即可。 如果小,则要变换位置 。
            if( arr[i] < v){
                j ++;
                swap(arr, j, i);
            }

        swap(arr, l, j);

        return j;
    }

    // 递归使用快速排序,对arr[l...r]的范围进行排序
    private static void sort(int[] arr, int l, int r){

        if( l >= r )
            return;
// 从一堆数组中,找一个元素(第0个),把它放到它该放的位置。返回它的索引
        int p = partition(arr, l, r);
        sort(arr, l, p-1 );
        sort(arr, p+1, r);
    }

 
 
}

归并排序

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/37f66390f7be010a0aaaefbe05cfa9a7.gif)

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/d5a1d4a3-5d61-4f76-a965-f11e40f8a55f.jpg)

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/9f8aaf97-33ed-4f74-afc7-994868de0951.jpg)

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class MergetSort {

    public static void main(String[] args) {
        int arr[] = { 8, 4, 5, 7, 1, 3, 6, 2 }; //
        
        
        System.out.println("排序前的时间是=" + date1Str);
        
        int temp[] = new int[arr.length]; //归并排序需要一个额外空间
        mergeSort(arr, 0, arr.length - 1, temp);
        
    }
    
    
    //递归使用 归并排序,将arr[left...right]范围进行排序
    public static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if(left < right) {
            int mid = (left + right) / 2; //中间索引
            //向左递归进行分解
            mergeSort(arr, left, mid, temp);
            //向右递归进行分解
            mergeSort(arr, mid + 1, right, temp);
            // 此时 ,假设分解成了2部分, 左边一半 有序, 右边一半有序,再进行合并操作
            //合并
            merge(arr, left, mid, right, temp);
            
        }
    }
    
    //合并的方法
    /**
     * 
     * @param arr 排序的原始数组
     * @param left 左边有序序列的初始索引
     * @param mid 中间索引
     * @param right 右边索引
     * @param temp 做中转的数组
     */
    public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        
        int i = left; // 初始化i, 左边有序序列的初始索引
        int j = mid + 1; //初始化j, 右边有序序列的初始索引
        int t = 0; // 指向temp数组的当前索引
        
        //(一)
        //先把左右两边(有序)的数据按照规则填充到temp数组
        //直到左右两边的有序序列,有一边处理完毕为止
        while (i <= mid && j <= right) {//继续
            //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
            //即将左边的当前元素,填充到 temp数组 
            //然后 t++, i++
            if(arr[i] <= arr[j]) {
                temp[t] = arr[i];
                t += 1;
                i += 1;
            } else { //反之,将右边有序序列的当前元素,填充到temp数组
                temp[t] = arr[j];
                t += 1;
                j += 1;
            }
        }
        
        //(二)
        //把有剩余数据的一边的数据依次全部填充到temp
        while( i <= mid) { //左边的有序序列还有剩余的元素,就全部填充到temp
            temp[t] = arr[i];
            t += 1;
            i += 1; 
        }
        
        while( j <= right) { //右边的有序序列还有剩余的元素,就全部填充到temp
            temp[t] = arr[j];
            t += 1;
            j += 1; 
        }
        
        
        //(三)
        //将temp数组的元素拷贝到arr
        
        t = 0;
        int tempLeft = left; // 

        while(tempLeft <= right) { 
            arr[tempLeft] = temp[t];
            t += 1;
            tempLeft += 1;
        }
        
    }

}

排序算法对比

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/a1d80208-81dc-4dff-a5ed-b7eee560c347.png)

常见查找算法

线性查找

low的一匹,就是根据所以,一个一个去对比

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/eb2f40da-b5a2-4aed-86e6-a381d514578b.png)

二分查找及其改进

![img](file:///C:/Users/Administrator/Documents/My Knowledge/temp/0770f581-43fe-40e9-8a2a-808a82cae82f/128/index_files/78a54b8c-0428-47ae-a472-13371eb269e9.jpg)

改进,比如 {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中, 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000

//注意:使用二分查找的前提是 该数组是有序的.
public class BinarySearch {

    public static void main(String[] args) {
        int arr[] = {1, 8, 10, 89, 1000, 1000, 1234};
         int resIndex = binarySearch(arr, 0, arr.length - 1, 2);
        System.out.println("resIndex=" + resIndex);
    }
 
    // 二分查找算法
   /**
     * @param arr     数组
     * @param left    左边的索引
     * @param right   右边的索引
     * @param findVal 要查找的值
     * @return 如果找到就返回下标,如果没有找到,就返回 -1
     */
    public static int binarySearch(int[] arr, int left, int right, int findVal) {

        // 当 left > right 时,说明递归整个数组,但是没有找到
        if (left > right) {
            return -1;
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) { // 向 右递归
            return binarySearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) { // 向左递归
            return binarySearch(arr, left, mid - 1, findVal);
        } else {
            return mid;
        }
   }
    
        //完成一个课后思考题:
    /*
     * 课后思考题: {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中,
     * 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000
     * 
     * 思路分析
     * 1. 在找到mid 索引值,不要马上返回
     * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
     * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
     * 4. 将Arraylist返回
     */

    public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {

        System.out.println("hello~");
        // 当 left > right 时,说明递归整个数组,但是没有找到
        if (left > right) {
            return new ArrayList<Integer>();
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) { // 向 右递归
            return binarySearch2(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) { // 向左递归
            return binarySearch2(arr, left, mid - 1, findVal);
        } else {
//           * 思路分析
//           * 1. 在找到mid 索引值,不要马上返回
//           * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
//           * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
//           * 4. 将Arraylist返回
            
            List<Integer> resIndexlist = new ArrayList<Integer>();
            //向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
            int temp = mid - 1;
            while(true) {
                if (temp < 0 || arr[temp] != findVal) {//退出
                    break;
                }
                //否则,就temp 放入到 resIndexlist
                resIndexlist.add(temp);
                temp -= 1; //temp左移
            }
            resIndexlist.add(mid);  //
            
            //向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
            temp = mid + 1;
            while(true) {
                if (temp > arr.length - 1 || arr[temp] != findVal) {//退出
                    break;
                }
                //否则,就temp 放入到 resIndexlist
                resIndexlist.add(temp);
                temp += 1; //temp右移
            }
            
            return resIndexlist;
        }

    }
    
}

插值查找

斐波那契查找

posted @ 2019-08-28 23:54  Scala偷走了我的微笑  阅读(441)  评论(0编辑  收藏  举报