初级排序算法
选择排序
选择排序,就是每次都从待排序序列中获得关心的值的最小的项,并将其与第一个项交换,依次循环,直到所有的项都排序完成。
/**
*功能描述:传入一个 int 类型的数组,进行排序,flag : true 升序,false 降序
*@param arr the array that needs to be sorted.
*@author Jason
*Date 2020-07-28 16:32
*/
private static int [] selectSort(int [] arr, boolean flag) {
for (int i = 0 ; i < arr.length - 1 ; i ++ ) {
int index = i;
for (int j = i + 1 ; j < arr.length ; j ++ ) {
if(flag == (arr[index] > arr[j])){
index = j;
}
}
if(i != index){
int tmp = arr[i];
arr[i] = arr[index];
arr[index] = tmp;
}
}
return arr;
}
这个排序算法是比较好理解的,通过上图也可以比较直观地看出排序的过程。
下面来看看该算法的两个特性:
1.运行的时间只和传入的数组的长度有关,与数组本身是否有序无关
在每次寻找最小元素的时候,都会对数组扫描一遍,并不会因为元素是否有序而减少扫描次数。
2.数组元素的交换次数与数组的长度是线性关系
每次扫描找到一个最小的元素时,都会进行一次交换。
插入排序
上述的选择排序算法中,对于一个接近有序的数组排序的时候,仍然是需要和乱序一样的排序时间,这就是一个可以优化的地方,那有没有一种排序方法,可以对一个接近有序的序列快速地排序?
答案是有的: 插入排序
我们这里和 选择排序做个对比:
- 和选择排序一样,他也是需要比较的,而且在正在排序的序列索引的左侧部分是一个已经有序的序列了,但是插入排序,左侧元素的具体位置,目前还不能确定,有可能在后续的过程发生更改,当排序的索引位于数组的右侧时,排序完成。
- 与选择排序不同的是,插入排序所需要的时间与序列的原本顺序有直接的关系,对于一个接近有序的序列使用插入排序会比乱序和逆序的快得多。
private static int [] insertSort(int[] arr, boolean flag) {
for (int i = 0 ; i < arr.length - 1; i ++ ) {
int tmp = arr[i+1];
for (int j = 0 ; j <= i ; j ++ ) {
if(flag == (arr[j] > arr[i + 1])){
if (i + 1 - j >= 0)
System.arraycopy(arr, j, arr, j + 1, i + 1 - j);
arr[j] = tmp;
}
}
}
return arr;
}
希尔排序
希尔排序是一个基于插入排序的一种快速排序算法。对于一般的插入排序算法而言,较大规模的乱序数组的排序就会很慢,因为它只会交换相邻的数组元素,元素只能一点一点地移动到一侧。希尔排序就不再是交换相邻的元素,而是不相邻的元素,对数组进行局部的排序,是的整个数组局部有序,随着间隔的减小,最后对整个数组进行一次插入排序,便可以完成对整个数组的排序。
上图就是以一个 gap=4
为例,将子序列排出,对各个子序列进行插入排序,之后便会将 gap
的值减小,直到 1 ,最后一次插入排序后,整个数组就已经排好序了。
/**
*功能描述:传入一个 int 类型的数组,进行排序,flag : true 升序,false 降序
*@param arr the array that needs to be sorted.
*@author Jason
*Date 2020-07-28 16:32
*/
private static int [] shellSort(int [] arr, boolean flag) {
int gap = arr.length >> 1;
while (gap > 0) {
for (int i = gap; i < arr.length; i ++ ) {
int tmp = arr[i];
int index = i - gap;
while (index >= 0 && flag == (arr[index] > tmp) ) {
arr[index + gap] = arr[index];
index -= gap;
}
arr[index + gap] = tmp;
}
gap = gap >> 1;
}
return arr;
}
希尔排序比选择排序和插入排序都要快,数组越大,优势越明显。
欢迎关注公众号
个人公众号会持续推送数据结构方面的文章或资源~~