递归与分治

x33g5p2x  于2022-06-08 转载在 其他  
字(3.2k)|赞(0)|评价(0)|浏览(406)

二分搜索

/**
 * 二分搜索
 */
public class BinarySearch {

    public static void main(String[] args) {
        int target = 88;

        int[] arr = {1,34,56,7,9,34,5,6,8};

        int index = binarySearch(arr, 0, arr.length - 1, target);
        System.out.println("target的下标为:"+index);
    }

    public static int binarySearch(int[] arr, int left, int right, int target) {
        if (left > right) return -1;

        int mid = (left + right) / 2;

        if (target == arr[mid]) {
            return mid;
        } else if (target < arr[mid]) {
            return binarySearch(arr, left, mid-1, target);
        } else {
            return binarySearch(arr, mid+1, right, target);
        }
    }
}

最小值问题

/**
 * 最小值问题
 */
public class Min {

    public static void main(String[] args) {
        int[] a = {12,3,43,5,-99,768,8,998,-34};
        System.out.println(min(a, 0, a.length-1));
    }
    public static int min(int[] arr, int low, int high) {
        if(low >= high)
            return arr[low];

        int mid = (low + high) / 2;

        int min_l = min(arr, low, mid);
        int min_r = min(arr, mid+1, high);

        if (min_l < min_r)
            return min_l;
        else
            return min_r;
    }
}

幂乘问题

/**
 * 幂乘问题
 */
public class Power {
    public static void main(String[] args) {
        System.out.println(power(2,7));
    }

    public static int power(int a, int n) {
        if (a == 0)
            return 0;
        if (n == 0)
            return 1;
        if (n == 1)
            return a;

        if (n%2 == 0) { // a为偶数
            return power(a, n/2) * power(a, n/2);
        } else {        // a为奇数
            return power(a, (n-1)/2) * power(a, (n-1)/2) * a;
        }
    }
}

归并排序

/**
 * 归并排序
 */
public class MergeSort {
    static int[] a = {10,5,9,4,3,7,8};
    static int[]  b = new int[a.length];

    public static void main(String[] args) {
        System.out.println("排序前:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
        mergeSort(a, 0, a.length-1);

        System.out.println();
        System.out.println("排序后:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }

    }

    public static void mergeSort(int[] a, int left, int right) {
        // 若 left==right 则说明只有一个元素,可以当做有序,因此也不需要在mergeSort了
        if (left < right) {
            int mid = (left + right) / 2;

            // 先分治
            mergeSort(a, left, mid);
            mergeSort(a, mid+1, right);
            // 再合并
            merge(a, b, left, mid, right);

            // 将临时数组的数据拷贝到 原数组中
            for (int i=left; i<=right; i++) {
                a[i] = b[i];
            }

        }
    }

    public static void merge(int[] a, int[] b, int left, int mid, int right) {
        int pos_l = left;
        int pos_r = mid+1;
        int k = left;

        while( pos_l<=mid && pos_r<=right ) {   // 两边序列都没遍历完
            if (a[pos_l] <= a[pos_r]) {
                b[k++] = a[pos_l++];
            } else {
                b[k++] = a[pos_r++];
            }
        }
        // 左边已经遍历完
        if(pos_l > mid) {
            for (int i = pos_r; i <= right; i++) {
                b[k++] = a[i];
            }
        } else {    // 右边已经遍历完
            for (int i = pos_l; i <= mid; i++) {
                b[k++] = a[i];
            }
        }

    }
}

快速排序

/**
 * 快速排序
 */
public class QuickSort {
    static int[] a = {5,7,3,4,8,6,9,1,2};

    public static void main(String[] args) {
        System.out.println("排序前:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
        quickSort(a, 0, a.length-1);

        System.out.println();
        System.out.println("排序后:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }

    /**
     * 快速排序
     */
    public static void quickSort(int[] a, int left, int right) {
        // 若 left==right 则说明只有一个元素,可以当做有序,因此也不需要再排序了
        if (left < right) {
            // 先构造中心轴(也是快速排序的核心)
            int p = partition(a, left, right);
            // 分治中心轴左侧的元素
            quickSort(a, left, p-1);
            // 分治中心轴右侧的元素
            quickSort(a, p+1, right);
        }
    }

    /**
     * 返回中心轴下标,该方法只交换不满足条件的两个元素,因此相对来说效率更高
     */
    public static int partition(int[] a, int p, int r) {
            int i = p,j = r + 1;
            int x = a[p];
            while(true)
            {
                while(a[++i]<x &&i<r);  // 跳过符合要求的(左小的元素)
                while(a[--j]>x);        // 跳过符合要求的(右大的元素)
                if(i>=j)
                {
                    break;
                }
                // 此时交换的是 不符合 左小右大的两个元素 , 这样效率较高
                swap(a, i, j);
            }

            a[p] = a[j];    // 此时a[j]是小于X的元素
            a[j] = x;       // 将X 放到中心轴下标
            return j;       // 返回中心轴
        }

    // 交换
    public static void swap(int[] arr, int ind1, int ind2) {
        int temp = arr[ind1];
        arr[ind1] = arr[ind2];
        arr[ind2] = temp;
    }

}

相关文章