Mini-Notes: 数据结构与算法-[第三部分]排序
来源:互联网 发布:碧姬芭铎 知乎 编辑:程序博客网 时间:2024/06/10 06:56
前言
这个Mini-Notes开始于2016年4月18日下午,我想要认认真真把它写好,我也会认认真真把它写好。
排序的应用:
- 唯一性测试——如何测试一个给定序列S中的元素是否两两相异?
- 删除序列S中的重复元素
- 中位数(median element) / 第k小元素的选择
- 频率统计——哪个元素在序列S中出现的次数最多?
- Find closest pair
- 集合的交与并
- 寻找目标数对——给定一个目标数z,如何检测是否存在两个整数x,y属于S,使得x+y=z?
各种排序算法的比较分析:
排序算法一:插入排序(Insertion Sort)
基本思想:
就像我们打牌的时候整理纸牌一样,每次新拿到一个纸牌,就把它插入到前面的已经有序的纸牌里面的合适位置。
一个插入排序的例子:
3 2 6 1 5(原始序列)
2 3 6 1 5(整理3之后)
2 3 6 1 5(整理6之后)
1 2 3 6 5(整理1之后)
1 2 3 5 6(整理5之后)
排序算法二:选择排序(Selection Sort)
基本思想:
扫描左边的无序的部分,找到最大的值,然后交换这个位置与最后一个位置的值(也就是把最大的放到最后一个位置)。
一个选择排序的例子:
3 2 6 1 5(原始序列)
3 2 5 1 6(最大的是6)
3 2 1 5 6(最大的是5)
1 2 3 5 6(最大的是3)
1 2 3 5 6(最大的是2)
1 2 3 5 6(最大的是1)
排序算法三:希尔排序(Shell Sort)
一个希尔排序的例子:
一开始对increment = 5进行排序,也就是每隔5个元素比较一次,进行插入排序;然后对increment = 3进行排序,也就是每隔3个元素比较一次,进行插入排序;最后再进行increment = 1的插入排序。
希尔排序的代码实现:
又一个希尔排序的例子:
对希尔排序的算法分析:
开始时inc的值较大,子序列中的对象较少,排序速度较快;随着序列进展,inc值逐渐变小,子虚列中对象个数逐渐变多,由于前面工作的基础,大多数对象已基本有序,所以排序速度仍然很快。
时间效率:
O(
空间效率:
O(1)——因为仅占用1个缓冲单元
算法的稳定性:
不稳定——因为49*排序后却到了49的前面
排序算法四:归并排序(Merge Sort)
归并排序是采用分治法(Divide and Conquer)的一个非常典型的例子。
基本思想:
- 如果序列的长度大于1,则把序列拆分为两个等长的子序列。
- 分别对两个子序列进行排序,使得这两个子序列内部是有序的。
- 合并两个有序的子序列为一个序列。
一个归并排序的例子:
归并排序的代码实现:
#include <iostream> // 归并排序 using namespace std;// 将两个有序子序列a[l, m]和a[m + 1, r]合并 void merge(int a[], int l, int m, int r, int t[]){ int lFirst = l; int rFirst = m + 1; int lLast = m; int rLast = r; int tIndex = 0; while (lFirst <= lLast && rFirst <= rLast) { if (a[lFirst] <= a[rFirst]) { t[tIndex] = a[lFirst]; lFirst++; } else { t[tIndex] = a[rFirst]; rFirst++; } tIndex++; } while (lFirst <= lLast) { t[tIndex] = a[lFirst]; lFirst++; tIndex++; } while (rFirst <= rLast) { t[tIndex] = a[rFirst]; rFirst++; tIndex++; } for (int i = 0; i < tIndex; i++) { a[l + i] = t[i]; }}void mergeSort(int a[], int l, int r, int t[]){ if (l < r) { int m = (l + r) / 2; mergeSort(a, l, m, t); // 左边子序列有序 mergeSort(a, m + 1, r, t); // 右边子序列有序 merge(a, l, m, r, t); // 合并两个有序的子序列 }}int main(){ int n; // the number of elements in the array cin >> n; int a[n]; // the original array for (int i = 0; i < n; i++) { cin >> a[i]; } int t[n]; // the sorted array mergeSort(a, 0, n - 1, t); for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << endl; return 0;}
归并排序的应用:逆序对
逆序对:
对于一个包含N个非负整数的数组A[1, ..n],如果有i < j且A[i] > A[j],则称(i, j)为数组A的一个逆序对。
例如:
数组(3, 1, 4, 5, 2)的逆序对有(3, 1), (3, 2), (4, 2), (5, 2)共4个
枚举:
O(
逆序对的代码实现:
int inverse_num = 0;void inverse_number(int* A, int x, int y, int* T){ if (y - x > 1) { int m = x + (y-x) / 2; // divide int p = x, q = m, i = x; merge_sort(A, x, m, T); // 递归求解 merge_sort(A, m, y, T); // 递归求解 while (p < m || q < y) { if (q >= y || (p < m && A[p] <= A[q])) { T[i++] = A[p++]; } else { T[i++] = A[q++]; reverse_num += m - p; // 对于右边的每个q,统计左边比它大的元素个数 } } for(int i = x; i < y; i++) { A[i] = T[i]; } }}
排序算法五:快速排序(Quick Sort)
基本思想:
两个指针left和right. left左边的都小于等于x, right右边的都大于x, 未知区域在中间
left和right交替移动,一旦发现不满足要求的元素就停下来.,交换这两个元素, 使同时满足要求。
好处:当相同元素比较多时较快
快速排序的代码实现:
#include <iostream> // 快速排序 using namespace std;int partition(int a[], int low, int high){ int pivot_item = a[low]; int left = low; int right = high; while (left < right) { // Move left while item <= pivot while (a[left] <= pivot_item && left < high) { left++; } // Move right while item > pivot while (a[right] > pivot_item && low < right) { right--; } if (left < right) { swap(a[left], a[right]); } } // right is the final position for the pivot a[low] = a[right]; a[right] = pivot_item; return right;}void quickSort(int a[], int low, int high){ int pivot_position; if (low < high) { pivot_position = partition(a, low, high); quickSort(a, low, pivot_position - 1); quickSort(a, pivot_position + 1, high); }}int main(){ int n; // the number of elements in the array cin >> n; int a[n]; // the original array for (int i = 0; i < n; i++) { cin >> a[i]; } quickSort(a, 0, n - 1); for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << endl; return 0;}
- Mini-Notes: 数据结构与算法-[第三部分]排序
- Mini-Notes: 数据结构与算法-[第一部分]图论
- Mini-Notes: 数据结构与算法-[第二部分]树
- 数据结构与算法分析之--->部分排序算法的实现
- 数据结构与算法部分
- 算法导论 第三部分 基本数据结构 笔记
- 【数据结构与算法】排序
- 数据结构与算法 -排序
- 数据结构与算法:排序
- 【数据结构与算法】排序
- [算法与数据结构] 排序
- 数据结构与算法:排序
- 数据结构与算法第三章
- 数据结构与算法 第三课
- 【数据结构与算法】排序算法
- 数据结构与算法排序算法
- 数据结构与算法-----排序算法
- [翻译]C#数据结构与算法 – 第三章基本排序算法
- 【机器学习 基本概念】泊松分布与泊松过程
- Matlab 绘图颜色选择
- springboot 集成dubbo,RPC 远程调用服务接口:提示服务空指针异常
- 按位异或的深入理解
- Spring+MyBatis双数据库配置
- Mini-Notes: 数据结构与算法-[第三部分]排序
- C语言 学生信息管理系统
- Dreamp
- Spring Task定时任务
- Linux中的文件与目录管理
- PHP微信APP支付,下单,处理异步回调
- magento中产品分页处理
- Linux笔记
- 剑指offer:二叉树中和为某一值的路径