0
点赞
收藏
分享

微信扫一扫

Java实现快速排序,详细注释


执行流程

① 从序列中选择一个轴点元素(pivot)
✓ 假设每次选择 0 位置的元素为轴点元素
② 利用 pivot 将序列分割成 2 个子序列
✓ 将小于 pivot 的元素放在pivot前面(左侧)
✓ 将大于 pivot 的元素放在pivot后面(右侧)
✓ 等于pivot的元素放哪边都可以
✓即最后轴点元素在序列中心处
③ 对子序列进行 ① ② 操作
✓ 直到不能再分割(子序列中只剩下1个元素)

快速排序——轴点构造流程

Java实现快速排序,详细注释_数据结构


快速排序——与轴点相等的元素

Java实现快速排序,详细注释_数据结构_02


cmp位置的判断分别改为<= 、>=会起到什么效果

Java实现快速排序,详细注释_java_03


快速排序算法的本质:将每个元素都转换成轴点元素。

◼ 如果轴点左右元素数量极度不均匀,最坏情况
 T n = T n − 1 + O n = O(n 2 )

◼ 为了降低最坏情况的出现概率,一般采取的做法是
随机选择轴点元素

代码实现

package com.mj.sort.cmp;

import com.mj.sort.Sort;

public class QuickSort<T extends Comparable<T>> extends Sort<T> {

@Override
protected void sort() {
sort(0, array.length);
}

/**
* 对 [begin, end) 范围的元素进行快速排序
* @param begin
* @param end
*/
private void sort(int begin, int end) {
if (end - begin < 2) return;

// 确定轴点位置 O(n)
int mid = pivotIndex(begin, end);
// 对子序列进行快速排序
sort(begin, mid);
sort(mid + 1, end);
}

/**
* 构造出 [begin, end) 范围的轴点元素
* @return 轴点元素的最终位置
*/
private int pivotIndex(int begin, int end) {
// 随机选择一个元素跟begin位置进行交换 即进行轴点的随机选择 这时候begin位置就是轴点元素
swap(begin, begin + (int)(Math.random() * (end - begin)));

// 备份begin位置的元素
T pivot = array[begin];
// end指向最后一个元素
end--;

while (begin < end) {
while (begin < end) {
if (cmp(pivot, array[end]) < 0) { // 右边元素 > 轴点元素
end--;
} else { // 右边元素 <= 轴点元素
array[begin++] = array[end]; //用右边的元素覆盖掉begin位置的元素,然后begin++
break; //覆盖完之后,换比较方向
}
}
while (begin < end) {
if (cmp(pivot, array[begin]) > 0) { // 左边元素 < 轴点元素
begin++;
} else { // 左边元素 >= 轴点元素
array[end--] = array[begin]; //用左边元素覆盖掉数组右边的end指向的元素,即大于他的放在右边。然后end--
break; //覆盖完之后,换比较方向
}
}
}
//当begin == end时,此时begin位置就是轴点元素最终的位置
// 将轴点元素放入最终的位置
array[begin] = pivot;
// 返回轴点元素的位置
return begin;
}
}


举报

相关推荐

0 条评论