快速排序-java

it2026-06-04  5

快速排序

原理

快递排序其实是一个递归的过程。

快速排序中任意指定一个数为中轴值,将小于该数的都放到它的左边,大于该数的都放到它的右边。然后对它的左子序列和右子序列继续做快速排序。

过程

规定序列左边的第一个数为pivot,两个指针left和right分别指向序列的左边和右边;因为后面递归还需要用到left和right,所以使用l和r保存left和right的值,使用l和r进行移动定位;从右边开始(因为我将最左边的数作为pivot,所以从右边开始,如果将最右边的数作为pivot,则从最左边开始),寻找比基准值小的数,就停住; 接着从左边开始,寻找比基准值大的数,停住;交换a[l]和a[r];依次反复,直到l和r相遇,将a[l/r]放到pivot所在的位置a[left],pivot放到a[l/r],一次快速排序就结束。此时pivot左边的数都比pivot小,右边都比pivot大。递归地对左子序列和右子序列做上面的过程。

代码实现

/** * 快速排序交换法 * 规定序列左边的第一个数为pivot,两个指针left和right分别指向序列的左边和右边 * 因为后面递归还需要用到left和right,所以使用l和r保存left和right的值,使用l和r进行移动 * r是从右边开始找比pivot小的数,l是从左边开始找比pivot大的数 * 从右边开始找,找到比pivot小的就停住,然后从左边开始找比pivot大的停住,交换两个指针指向的数。(前提是l<r) * 如果在寻找的过程中,l=r,就将pivot和a[l](或a[r])交换 * * @param a * @param left * @param right */ public static void quickSort(int[] a, int left, int right) { if (left >= right) return; int pivot = 0; int l = left; int r = right; int temp; while (true) { pivot = a[left]; while (a[r] >= pivot && l < r) r--; while (a[l] <= pivot && l < r) l++; if (l == r) break; temp = a[r]; a[r] = a[l]; a[l] = temp; } if (l != left) { a[left] = a[l]; a[l] = pivot; } //对左子序列进行快速排序 quickSort(a, left, l - 1); //对右子序列进行快速排序 quickSort(a, l + 1, right); } /** * 快速排序移位法 * 令两个指针left和right分别指向数组的左边和右边,将数组中的第一个值看做基准值pivot,从右边开始,寻找比基准值小的数,放到a[left]的位置; * 然后从左边开始,寻找比基准值大的数,放到a[right]的位置;依次反复,直到left和right相遇,那么第一次快速排序就结束。 * * @param a */ public static void quickSort1(int[] a, int left, int right) { if (left >= right) return; int pivot = a[left]; int l = left; int r = right; while (true) { while (a[r] >= pivot && l < r) { r--; } a[l] = a[r]; while (a[l] <= pivot && l < r) { l++; } a[r] = a[l]; if (l == r) break; } a[l] = pivot; quickSort1(a, left, l - 1); quickSort1(a, l + 1, right); }

以上两段代码都可实现快速排序,经过测试排序1000万数据平均用时1.048s。移位法和交换法的区别不是很大,通过debug可以看到整个排序的详细过程。

最新回复(0)