序论:
最近在学《算法(第四版)》,学到了选择排序和插入排序,记录下来加深印象便于复习。
默认排序为从小到大,使用简单的int 类型排序,便于理解。(使用java语言,不过语言特性几乎用不到。)
1.选择排序
排序思想
数组: 4 2 7 1
首先索引 int temp = 0; a[temp] = 4 ;
然后找到索引右侧(含当前位置)的最小值,1,将 1 的位置与 索引指向的位置进行交换。
索引后移。
循环上述过程
2为索引右侧最小值,不进行移动,而索引右移一位。
4为最小值,与7及进行交换位置。
索引移到位最尾端,结束排序。
选择排序完成。
代码施工
public static void sort1(int[] a) { //选择排序. int N = a.length; //得到循环次数 N,即是数组的大小。 for (int i = 0; i < N; i++){ int min = i; for(int j = i + 1; j < N; j++){ if(a[j] > a[min]) min = j; //循环,找到右侧最小值 } exch(a,i,min); //进行交换(不进行代码描述,防止干扰。) } }
分析
这个算法的复杂度约为 : N²/2 次比较,N次交换
特点
1. 运行时间与数组内容无关:无论怎样的数组,只要长度相同,时间几乎相同。(A数组只有两个数字位置相反,b 数组完全无序,c数组倒序,三者时间相同.)
2. 数据移动最少 : 大部分算法增长数量级都是线性对数或是平方级别。
2插入排序
排序思想
数组: 4 2 7 1 0
索引从第二个开始。
a[1]比a[0]小,交换位置
索引右移一位。
a[2]比a[1]小,进行交换
索引后移。
开始进行交换。
0 < 4,进行交换
0<2,进行交换
0<1,进行交换
排序完成。
看起来很啰嗦,但实际上电脑就是这样操作。
代码施工
void sort(int[] a) { //插入排序 int N = a.length; //获得数组的长度。即外循环次数。 for (int i = 1; i < N; i++) { for (int j = i; j > 0 && a[j] < a[j - 1]; j--) { exch(a, j, j - 1); } } }
分析
最坏情况为 :~N²/2 次比较和 ~N²/2 次交换
最好情况为 :N - 1次比较和 0 次交换。
特点
当满足以下几点中几条时,推荐使用插入排序
* 数组中的每个元素距离它的最终位置都不远
* 一个有序的大数组接一个小数组。
* 数组中只有几个元素的位置不正确。
最后推荐一下:一个用动图展示排序的网站
其中,SEL是(select )选择排序,INS是 (insert)插入排序