快速排序

快排

时间复杂度O(NlogN),

最坏情况下每次分割为两个长度为1,和n-1的小块,变为冒泡排序时间复杂度为O(N²)

public class MyQuickSort {

	public static void MyQuickSort(int[] a, int low, int high) {
		if(low >= high) {
			return;
		}

		int first, last, key;
		first = low;
		last = high;
		key = a[first];
        
        // 挖坑填数 + 分治法
		while(first < last) {
			while(first < last && a[last] >= key) {
				last--;
			}
			if(first < last) {
				a[first] = a[last];
				first++;
			}
			while(first < last && a[first] <= key) {
				first++;
			}
			if(first < last) {
				a[last] = a[first];
				last--;
			}
		}
		a[first] = key;
		MyQuickSort(a, low, first - 1);
		MyQuickSort(a, first + 1, high);
	}

	private static void arrayPrint(int[] a) {
		System.out.println();
		for (int i : a) {
			System.out.print(i + " ");
		}
	}

	public static void main(String[] args) {
		int[] a = {6, 5, 1, 7, 4, 3, 5, 1, 6, -10, -1};
		arrayPrint(a);
		MyQuickSort(a, 0, a.length - 1);
		arrayPrint(a);
	}


}

改进

随机锚点

不再是固定取第一个值,而是在序列里面随机取一个作为锚点。

具体做法:可以随机取锚点后和第一个位置交换,然后继续上述算法。

三数取中法

直接取最左端、中间和最右端三个数

交换顺序,使得中间小两边大,同时使得左边的数小于右边的数。

public class Test09 {

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    private static void printArr(int[] arr) {
        for (int anArr : arr) {
            System.out.print(anArr + " ");
        }
    }

    private static int partition(int[] arr, int left, int right) {
        // 采用三数中值分割法
        int mid = left + (right - left) / 2;
        // 保证左端较小
        if (arr[left] > arr[right])
            swap(arr, left, right);
        // 保证中间较小
        if (arr[mid] > arr[right])
            swap(arr, mid, right);
        // 保证中间最小,左右最大
        if (arr[mid] > arr[left])
            swap(arr, left, mid);
        int pivot = arr[left];
        while (right > left) {
            // 先判断基准数和后面的数依次比较
            while (pivot <= arr[right] && left < right) {
                --right;
            }
            // 当基准数大于了 arr[right],则填坑
            if (left < right) {
                arr[left] = arr[right];
                ++left;
            }
            // 现在是 arr[right] 需要填坑了
            while (pivot >= arr[left] && left < right) {
                ++left;
            }
            if (left < right) {
                arr[right] = arr[left];
                --right;
            }
        }
        arr[left] = pivot;
        return left;
    }

    private static void quickSort(int[] arr, int left, int right) {
        if (arr == null || left >= right || arr.length <= 1)
            return;
        int mid = partition(arr, left, right);
        quickSort(arr, left, mid);
        quickSort(arr, mid + 1, right);
    }


    public static void main(String[] args) {
        int[] arr = {6, 4, 3, 2, 7, 9, 1, 8, 5};
        quickSort(arr, 0, arr.length - 1);
        printArr(arr);
    }
}

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页