查找与排序

二分查找

import java.util.ArrayList;
import java.util.List;

public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1, 8, 9, 10, 234, 234,234, 1000, 1234};
        int i = binarySearch(arr, 0, arr.length - 1, 234);
        System.out.println(i);
        List<Integer> index = binarySearch2(arr, 0, arr.length - 1, 234);
        System.out.println(index);
    }
    // 只能找出一个值的下标 递归实现
    public static int binarySearch(int[] arr, int left, int right, int findVal){
        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 if (findVal == midVal){
            return mid;
        }
        return -1;
    }
    // 循环实现
    public static int binarySearch3(int[] arr, int target){
        int left = 0;
        int right = arr.length - 1;
        while(left <= right){
            int mid = (left + right) / 2;
            if (arr[mid] == target){
                return mid;
            }else if(arr[mid] > target){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        return -1;
    }

    // 可以找出多个值的下标
    public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal){
        if (left > right){
            return new ArrayList<>();
        }
        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 if (findVal == midVal){
            int temp = mid - 1; // 辅助变量
            List<Integer> result = new ArrayList<>();
            while(true){
                // 向中间值的左边找 因为为有序的数组,所以只要找到不等于findVal的值就饿可以直接退出循环
                if (temp < 0 || arr[temp] != midVal){
                    break;
                }
                result.add(temp);
                temp -= 1;
            }
            result.add(mid); // 添加中间值的下标
            temp = mid + 1;
            while(true){
                // 向中间值的右边找 因为为有序数组 所以只要找到不等于findVal的值就可以直接退出循环
                if (temp > arr.length - 1 || arr[temp] != midVal){ 
                    break;
                }
                result.add(temp);
                temp += 1;
            }
            return result;
        }
        return new ArrayList<>();
    }
}
排序算法.png

冒泡排序

public static void bubbleSort(int[] arr){ // 时间复杂度为o(n^2)
        int temp;
        boolean flag = false; // 标记变量
        for (int i = 0; i < arr.length - 1; i++) { // 一共进行多少躺排序
            for (int j = 0; j < arr.length - i - 1; j++) { // 每一趟排序都找出最大值 往后移
                if (arr[j] > arr[j+1]){
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (!flag){ // 如果一趟排序中一次交换都没有出现就退出循环
                break;
            }else {
                flag = false; // 重置flag方便下次判断
            }
        }
    }

插入排序

public static void insertSort(int[] arr) {
        // 从第二个元素开始
        for (int i = 1; i < arr.length; i++) {
            int insertValue = arr[i]; // 要插入的元素
            int insertIndex = i - 1; // 插入的位置
            while (insertIndex >= 0 && insertValue < arr[insertIndex]) { // 寻找位置
                arr[insertIndex + 1] = arr[insertIndex]; // 比它大的元素后移
                insertIndex--; // 向前走
            }
            // 因为之前index = i - 1 如果没有进入到while循环就不需要插入(index = i - 1)
            if (insertIndex + 1 != i) {
                arr[insertIndex + 1] = insertValue; // 把要元素插入到查找到的位置
            }
        }
    }

快速排序

public static void quickSort(int[] arr, int left, int right){
        int l = left; // 左下标 0
        int r = right; // 右下标 5
        // pivot 中轴值
        int pivot = arr[(left + right) / 2]; // 78
        int temp = 0;// 临时变量
        // while循环的目的是让pivot值小放到左边 比pivot值大放到右边
        while (l < r){
            while(arr[l] < pivot){ // 找出在pivot的左边比pivot大或者等的值的下标
                l += 1;
            }
            while(arr[r] > pivot){ // 找出在pivot的右边比pivot小或者等的值的下标
                r -= 1;
            }
            if (l >= r){
                break;
            }
            //交换pivot左边比他大的值 pivot右边比他小的值 
            temp = arr[r];
            arr[r] = arr[l];
            arr[l] = temp;

            if (arr[l] == pivot){ // 如果左边的这个值是等于pivot的 r--向前移动
                r--;
            }
            if (arr[r] == pivot){ // 如果右边的这个值是等于pivot的 l++ 向后移动
                l++;
            }
        }
        if (l == r){
            l += 1; // 增加l的值 不然可能出现栈溢出
            r -= 1; // 减小r的值 不然可能出现栈溢出
        }
        if (left < r){ // 在左边递归
            quickSort(arr,left,r);
        }
        if (right > l){ // 在右边递归
            quickSort(arr,l,right);
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。