java实现快速排序

163 阅读2分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

快速排序

说的简单点儿就是:你现在要对一串数据进行排序(如 9 4 6 3 11 7),现在有一种办法就是:

假设你看到9这个数字比较舒服 你就选择5作为一个分界点开始排序 经过一轮排序下来 9左边的数都比9小 9右边

的数都比9大,这只是一轮 第二轮就可以分两边了 然后依次类推 在这个过程中就需要用到递归 我们还可以知道

要对左右两边分别递归 最后就出来。这是我对快速排序最简单的理解。

我们对数组 9 4 6 3 11 7 进行了第一轮排序;选择9作为关键字  那么在一轮排序下来后 9左边的数都比9小 9右

边的数都比9大 那么又分别对9左边的数进行排序递归 对右边的数进行排序递归

具体代码的实现的相关注释在代码中:

	public static void sort(int[] a, int low, int high) {
		// 已经排完
		if (low >= high) {
			return;
		}
		int l = low;
		int r = high;
 
		// 保存基准值
		int key = a[l];
		while (l < r) {
			// 从最右边开始进行比较 如果找到比关键字小的就要将值放在左边去
			while (l < r && a[r] >= key)
				r--;
			a[l] = a[r];
			// 从最左边开始进行比较 如果找到比关键字大的就将值放到右边去
			while (l < r && a[l] <= key)
				l++;
			a[r] = a[l];
		}
		// 关键字 默认为排序数组的第一位 当然也可以自己选择
		a[l] = key;
		// 对关键字左边的数进行递归
		sort(a, low, l - 1);
		// 对关键字右边的数字进行递归
		sort(a, l + 1, high);
	}
 
	public static void main(String[] args) {
		int[] arr = { 9, 4, 6, 3, 11, 7 };
		sort(arr, 0, 5);
		for (int i = 0; i < 6; i++) {
			System.out.println(arr[i]);
		}
	}

结果

image.png

举例

数组a[]中找出第k小的元素。 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的

具体代码的实现的相关注释在代码中:

/**
 * 数组a[]中找出第k小的元素。 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的
 * 
 * @author fls
 *
 */
public class _14 {
    public static int quickSelect(int a[], int l, int r, int k) {
        Random rand = new Random();
        int p = rand.nextInt(r - l + 1) + l;
        // 产生一个关键字 并且将关键字放在最后的最后去
        int x = a[p];
        int tmp = a[p];
        a[p] = a[r];
        a[r] = tmp;
        // 类型于两个指针 i指向第一个 位置 j指向关键字位置
        int i = l, j = r;

        while (i < j) {
            // 如果a[i]的值小于关键字就i++
            while (i < j && a[i] < x)
                i++;
            if (i < j) {
                // 当a[i]>关键字 就将关键字做一个改变 就开始移动j的位置
                a[j] = a[i];
                j--;
            }

            while (i < j && a[j] > x)
                j--;
            if (i < j) {
                a[i] = a[j];
                i++;
            }
        }
        a[i] = x;
        p = i;
        if (i - l + 1 == k)
            return a[i];
        if (i - l + 1 < k)
            // 此处为待填的空
            return quickSelect(a, i + 1, r, k - (i - l + 1));

        else
            return quickSelect(a, l, i - 1, k);
    }

    public static void main(String args[]) {
        int[] a = { 1, 4, 2, 8, 5, 7 };

        System.out.println(quickSelect(a, 0, 5, 4));
    }

简单说下这个代码的意思:这个代码就是给你一个数组 让你找出第k小的元素 那么首先我们就要对数组元素进行排

序 这里关键字的选择就是随机选择的 其中的i j 就相当于我们上一个代码中的l r 所以这个好理解

这里需要注意的是关于k

(i - l + 1 < k)说明你所要找的第k小的元素不在你关键字所排序的左边 那么就在右边 那么你在对右边排序的时

候 就相当于是右边 的 k - (i - l + 1)小 quickSelect(a, i + 1, r, k - (i - l + 1));

(i - l + 1 < k)就和上面的恰恰相反 这个就直接quickSelect(a, l, i - 1, k) 结果:

image.png