排序

快排

  • 选主元
    • 经典快排:选数组最后一个元素
    • 将数组第一个,中间位置,最后1个位置三个数交换达到排序的目的,将中间位置的和最后一个位置的交换
    • 随机函数选择1个与最后一个位置的交换
  • 划分子集
    • int i = left - 1, j = right
    • ++i,–j . 2个指针左指针和右指针,和主元比较,相向行驶。2个while循环
    • i < j 时 交换(交换时的arr[i] >= 主元,交换时的arr[j] <= 主元),否则退出循环
    • i+1的位置即是本轮主元的最终位置
 private static int partition2(int[] array, int left,  private static int partition2(int[] array, int left, int right) {

       //选主元
        int privot = array[9];
       //划分子集
        int i = left - 1,j = right;
        for (;;){
            //大于等于的放右边
            while (array[++i] < privot){}//红色警报
            while (array[j--] > privot){}//红色警报
            //和主元相等的时候也交换
            if (i < j){
                swap(array,i,j);
            }else{
                break;
            }
        }
        swap(array,i,right);
        return i ;
    }
 public static void quickSort(int a[],int left,int right){
        if (left < right){
            int q = partition2(a,left,right);
            quickSort(a,left,q-1);
            quickSort(a,q +1 ,right);
        }
    }
void quick_sort(int[] arr,int length){
        quickSort(arr,0,length - 1);
    }

平均情况下时间复杂度: O(nlogn),空间复杂度O(logn)

最快情况下时间复杂度: O(n^2^) ,空间复杂度O(n)

注 :数组中元素全部相同时,不交换的情况下一轮就是O(n) ,整体就是O(n^2^)

归并排序

算法思想:采用分治的策略,选取中间位置,将数组划分为2,然后合并,递归的处理左边,递归的处理右边。

合并是合并2个有序子数组,要1个辅助数组。

public static void mergeSort(public static void mergeSort(int[] arr) {
	if (arr == null || arr.length < 2) {
		return;
	}
	mergeSort(arr, 0, arr.length - 1);
}

public static void mergeSort(int[] arr, int l, int r) {
	if (l == r) {
		return;
	}
	int mid = l + ((r - l) >> 1);
	mergeSort(arr, l, mid);
	mergeSort(arr, mid + 1, r);
	merge(arr, l, mid, r);
}

public static void merge(int[] arr, int l, int m, int r) {
	int[] help = new int[r - l + 1];
	int i = 0;
	int p1 = l;
	int p2 = m + 1;
	while (p1 <= m && p2 <= r) {
		help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= m) {
		help[i++] = arr[p1++];
	}
	while (p2 <= r) {
		help[i++] = arr[p2++];
	}
	for (i = 0; i < help.length; i++) {
		arr[l + i] = help[i];
	}
}

快排和归并都是用分治的策略。

归并排序时间复杂度:O(nlogn),空间复杂度O(n)

image-20200520114634599

  1. 堆排序

    ①先理解堆结构,有一种O(n)的算法把一个数组调整成大根或者小根堆

    ②③

堆结构非常重要,建堆O(n),被火车撞了都不能忘记。最大的亮点是形成堆后,进来1个,O(Logn)可以搞定

image-20200522111135453

image-20200718111809940

合并两个有序数组

https://leetcode-cn.com/problems/merge-sorted-array/

用归并的方法,从后往前扫描。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!