快速排序

1.快速排序

  • 1.基本思想:
    • 1 从序列中选择一个轴点元素(pivot)
      假设每次选择 0 位置的元素为轴点元素
    • 2 利用 pivot 将序列分割成 2 个子序列
      将小于 pivot 的元素放在pivot前面(左侧)
      将大于 pivot 的元素放在pivot后面(右侧)
    • 3 对子序列进行 ① ② 操作
      image


public class QuickSort {

	// 需要稍作调整,非完整代码
	public 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位置进行交换
		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];
					break;
				}
			}
			while (begin < end) {
				if (cmp(pivot, array[begin]) > 0) { // 左边元素 < 轴点元素
					begin++;
				} else { // 左边元素 >= 轴点元素
					array[end--] = array[begin];
					break;
				}
			}
		}
		
		// 将轴点元素放入最终的位置
		array[begin] = pivot;
		// 返回轴点元素的位置
		return begin;
	}
}

关于复杂度

所谓的o(n)是指选取第一个轴点元素,需要遍历数组中的所有元素,即:数组中的元素与轴点元素进行比较

  • 1 最坏情况:选取的轴点元素后,只有一侧有元素
  • 2 选取轴点元素,尽量采用随机的原则,降低出现最坏情况的可能性
    image

快速排序 – 与轴点相等的元素的处理规则

  • 与轴点元素相等那么移动元素,向前向后移动
    image
    image

总结

1.随机选取轴点元素,大的往后,小的往前、
2.降低出现最坏可能性
3.分治思想
4.递归
5.掉头(3个while循环)
6.双指针

posted @ 2021-03-14 20:48  jacksonma  阅读(49)  评论(0)    收藏  举报