1.插入排序
2.分治排序法,快速排序法
3.冒泡排序 low版
4.冒泡排序 bigger版
5.选择排序
6.归并排序
7. 其他排序
8. 比较
1.插入排序
插入排序就是往数列里面插入数据元素。 一般我们认为插入排序就是往一个已经排好序的待排序的数列中插入一个数,使得插入这个数之后,数列仍然有序。
二分插入排序也是用了分治法的思想去排序的。 实际上二分就是使用二分查找来找到这个插入的位置,剩余的插入的思想其实和直接插入排序一样。
插入排序的原理
插入排序实际上把待排序的数列分为了两部分,一部分已排好序,另一部分待排序。我们下面还是以一组实际数据为例进行讲解。假设待排序的数列为 63、88、34、99、38、55、9,首先我们将数列储存为如图 1 所示。
图 1 待排序的数列的初始状态
这时,全部数列都为待排序部分,我们开始一点点地进行插入排序。
首先把63 拿出来,这是第 1 个元素,不需要排序。这时,已排好序的部分已经有一个元素了,就是 63,而剩余的元素为待排序的部分。
接着我们把 88 拿出来,与前面的元素相比较,发现比 63 大,符合我们把数列小到大排序的想法,无须交换。这时已排好序的部分又增加了一个新成员,而待排序部分相应地少了一个元素。
之后我们看 34,比前面的元素 88 比较,发现比 88 小,我们把 34 拿出来,让它在外面等一下,把88向后移动一位,此时数组的情况如图 2 所示。
图 2 待排序的数列的状态,将 88 向后移动一位
接下来我们继续向前比较,直到比较到第 1 个元素为止。这时发现 34 仍然比 63 小,继续把 **63 **向后移动,这时的状态如图 3 所示。
图 3 待排序的数列的状态,将 63 向后移动一位
现在发现已经比较到第 1 个元素了,第 1 个位置的** 63 **元素需要移动,所以第 1 个位置空出来了,那就把拿出来的 34 放到第 1 个位置上,这时数列状态变为 34、63、88、99、38、55、9。
现在,已排好序的数列部分为 34、63、88,剩余的后面部分为待排序部分。我们继续看后面的元素,该处理 99 了,与前 1 个元素比较,发现比 88 大,由于前面的部分已排好序,所以 88 就是前面数列中最大的,99 比 88 大,肯定也比前面的所有元素都大,不用继续比较了,可以直接把 99 加入前面的已排好序的部分了。
接下来处理 38,与前 1 个元素比较,发现比 99 小,于是把 38 拿出来,将 99 向后移动,这时的待排序的数列的状态如图 4 所示。
图 4 待排序的数列的状态,将 99 向后移动一位
接着继续用 38 与 88 比较,发现比 88 小,88 继续后移一位;继续与 63 比较,发现比 63 小,63 也后移一位,这时的数组状态如图 5 所示。
图 5 当前的待排序的数列状态
此时继续用 38 与 34 比较,发现比 34 大,不管 34 前面有没有元素,都不用继续比较了,可以直接把 38 放在那个空位上。此时的数组状态变为 34、38、63、88、99、55、9。
后面就是分别处理 55 和 9 这两个元素了。通过上面的几次移动与比较,我们应该可以自己完成对这两个元素的插入了。最后当待排序的部分已经没有了时,整个数列就已经完成所有的排序操作了。
public class insertSort{
public static void sort(int[] arr){
if(arr.length >= 2){
for(int i = 0; i < arr.length; i++){
//挖出一个要用来插入的值,同时位置上留下一个可以存新的值的坑
int x = arr[i];
int j = x - 1;
//在前面有一个或连续多个值比x大的时候,一直循环往前面找,将x插入到这串值前面
while( j>=0 &&arr[j] > x){
//当arr[j]比x大的时候,将j向后移一位,正好填到坑中
arr[j+1] = arr[j];
j--;
}
//将x插入到最前面
arr[j+1] = x;
}
}
}
}