什么是插入排序!简单的介绍一下它的思想(假设为升序):在已经排好序的数组内,插入新的元素,从后往前找,当找到某个比它小的数,则停止,并将它插入这个与上一个数之间。先给大家看个图:
具体算法描述如下:
1.从第一个元素开始,因为只有一个元素,所以它有序。
2.拿它后面的一个元素和它进行比较。
3.它后面的元素比它大,把他往后移,并把它后面的元素赋给它原来的位置。
4.重复3的动作,直到找到比它小或者相等的元素,将该元素插入到比它小的元素后面
5.重复2~5的操作
我们先来看看代码:
<span style="font-size:14px;"> public static void sort(int[] array){
for (int i = 1; i < array.length; i++){
int j = i - 1;
int temp = array[i];
while((j >= 0) && (array[j] > temp)){
array[j + 1] = array[j];
j--;
}
array[j+1] = temp;
}
}</span>
比较简洁,也许你会说可以从前往后比较吗,我会说可以,但是,为了分清楚是跳出循环的是遍历到最后一个还是找到第一个比它的数,还是第一个数就是比它大,我们需要引入一个标志位,具体如下:
private static void move(int[] array, int from, int to){
for(int i = to; i > from; i--){
array[i] = array[i - 1];
}
}
public static void sort1(int[] array){
for(int i = 1; i < array.length; i++) {
int j = 0;
boolean flag = false;
while(!flag && (j < i)){
if (array[i] < array[j]) {
flag = true;
}
j++;
}
if ((flag)) {
int temp = array[i];
move(array, --j, i);
array[j] = temp;
}
}
}
看起来就比上面复杂多了,所以还是推荐从后往前比较。
可以很轻易的得到,时间复杂度是O(n^2)的,空间复杂度是O(n) + O(1),最优时间复杂度为O(n).
到这好像还可以做点什么,因为我们知道,对元素一个一个进行比较是可以优化的,这样的时间复杂度是O(n),假如采用二分法的话,时间复杂度是O(logn)。这样好像能提高不少。
public static int binarySearch(int[] array, int begin, int end, int num){
if (array[end] < num){
return end + 1;
}
int middle = (begin + end)/2;
while(middle > 0){
if (array[middle] == num){
return middle + 1;
}else if (array[middle] > num) {
end = middle;
}else if (array[middle] < num) {
begin = middle;
}
middle = (begin + end)/2;
}
if (array[middle] > num)
return middle;
return end;
}
public static void sort2(int[] array){
for (int i = 1; i < array.length; i++){
int temp = array[i];
int j = binarySearch(array,0, i-1, temp);
move(array, j, i);
array[j] = temp;
}
欢迎交流