排序算法学习经验(三)
来源:互联网 发布:淘宝首页显示不全 编辑:程序博客网 时间:2024/06/10 22:28
上次总结了一下归并排序及其优化的思路,接上次,这次详细分析一下快速排序的具体思路,方便大家理解。
关键点提要:
快速排序、双路快排、三路快排
快速排序:
快速排序相对于归并排序,不需要额外的数组空间,因此空间效率很高。而且,快速排序是许多系统调用库函数的默认排序函数。其思路就是将一组元素,选定一个标定点,然后将整个元素分成两部分,左半部分小于或者等于这个标定点,右半部分大于等于这个标定点;然后分别又对分成的两部分同样进行上面的操作:选标定点过后排序。这样操作下去,整个数组就变成有序的了。
先看举例:
第一步:选定标定点
第二步:考虑当前元素的大小,假设大于标定点,则直接合并,若小于标定点,则交换再合并。
大于标定点:
小于标定点:
第三步:依次操作直到最后一个元素,然后交换标定点和最后一个小于标定点的值。则完成了标定点j左边的元素全部小于等于v,右边全部大于v的操作
结合图片理解代码:
#pragma once#include<iostream>using namespace std;// 对arr[l...r]范围的数组进行插入排序template<typename T>void insertionSort(T arr[], int l, int r){ for (int i = l + 1; i <= r; i++) { T e = arr[i]; int j; for (j = i; arr[j - 1] > e && j > l; j--) { arr[j] = arr[j - 1]; } arr[j] = e; }}template<typename T>int partition(T arr[],int l, int r){ swap(arr[l], arr[rand() % (r - l + 1) + l]); T p = arr[l];//设置标定点 int i = l + 1;//当前要考虑元素下标 int j = l;//最后一个小于p的元素 while (i <= r) { if (arr[i] <= p) { swap(arr[i], arr[j + 1]); j++; } i++; } swap(arr[j], arr[l]); return j;}template<typename T>void __quickSort(T arr[], int l, int r){ //递归到底的情况,和前面类似用插入排序 if (r - l <= 9) { insertionSort(arr, l, r); return; } int p = partition(arr, l, r);//标定点 //递归到底层后数组就成为有序的数组 __quickSort(arr, l, p - 1);//左层递归调用,继续partition __quickSort(arr, p + 1, r);//右层递归调用,继续partition}template<typename T>void quickSort(T arr[], int n){ srand(unsigned(time(NULL))); //设置随机种子 __quickSort(arr, 0, n - 1); //初次调用}
以上就是对基础快速排序的全部实现了。这个算法有一个致命缺陷,就是在partition操作时,分组极其不平衡,导致分组会成为一个极端,左边元素为0或者右边元素为0。例如一个大量重复数组,只包含1,2,3三种元素,进行排序,代码中会将2分到一边,如果3元素个数很少,就会导致12的总数量很大,导致不平衡。为了减少这些情况的出现,下次将会分析一下快速排序的改进,也就是双路快排以及三路快排的原理以及实现。
阅读全文
0 0
- 排序算法学习经验(三)
- 排序算法学习经验(一)
- 排序算法学习经验(二)
- 排序算法学习经验(四)
- 算法学习(排序三)快速排序
- 算法学习(三)堆排序
- 算法学习(三)----归并排序
- 算法学习(三)--插入排序
- 算法分析学习笔记(三) - 排序算法(上)
- 算法分析学习笔记(三) - 排序算法(下)
- 排序算法(三)
- 排序算法(三)
- 排序算法(三)
- 算法导论学习笔记(三):堆排序
- 算法学习(三)——选择排序
- 算法学习之排序算法(三)(选择排序法)
- 算法学习之三:快速排序
- 排序算法小记(三)
- ASP.NET Core 网站发布到Linux服务器
- EGit使用
- 在TCP半开连接上发送数据,结果怎样?
- 《Machine Learning》第四讲 正则化(regularization)
- 捕获promise异常,不能用onerror
- 排序算法学习经验(三)
- java-collection
- SQL教程——基本命令
- 过滤器拦截所有手机端重定向
- VIN码/车架号识别,手机移动端OCR扫描
- 第一周周考
- 面试小记
- PHP学习笔记
- python数据结构之树和二叉树(先序遍历、中序遍历和后序遍历)