插入排序
基本思想
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法描述:
1. 从第一个元素开始,默认该元素已排序。
2. 取出下一元素,在已排序的元素序列中从后向前扫描。
3. 如果该元素大于新元素,就将该元素移到下一位置。
4. 重复步骤3,直到找到一排序的匀速小雨或等于新元素的位置
5. 将该元素插入到该位置后。
6.重复步骤2~5。
代码实现
public static void insertSort(int[] arr){
int index,temp,current;
for(int i=1;i<arr.length;i++){
index =i-1;
current =arr[i];
while(index>=0 && current<arr[index] ){
arr[index+1] = arr[index];
index--;
}
arr[index+1] = current;
System.out.println( "第"+i+"次:");
System.out.println(java.util.Arrays.toString(arr));
}
}
index是待插入的位置的前一个位置,current保存的是用去比较的元素,如果遇到比current大的元素,就把该元素向前移一位且index-1,while循环是一个不断比较的过程,把比待插入元素大的元素都向后移一位,直到遇到比待插入元素小的位置,把待插入元素插入进去。
容易出错的地方
- current表示待插入元素需要使用临时变量存储而不能用arr[i]表示,因为当满足while条件后arr[i]被前一个元素置换了。
- index是可以等于0的,等于0即在数组下标0位置进行插入。
希尔排序
基本思想
希尔排序是把带排序序列按下标一定增量进行分组,再对每一组进行插入排序,随着增量逐渐减少,当增量减至1时,整个序列成了一组,再进行最后一次插入排序即完成排序。
代码实现
public static void shellSort(int[] arr){
int current,j;
for(int gap = arr.length/2;gap>0;gap/=2){
for(int i= gap;i<arr.length;i++){
j=i;
current = arr[j];
while(j-gap>=0&&arr[j]<arr[j-gap]){
arr[j] = arr[j-gap];
j-=gap;
}
arr[j] = current;
System.out.println(java.util.Arrays.toString(arr));
}
}
}
希尔排序的时间复杂度取决与增量gap的选取,在n l o g 2 log_2 log2n~n^2之间。如当gap直接取值为1时时间复杂度就是 n^2 ,网上普遍说是n^1.3,但是都没有推算过程。
需要注意的地方
- 第二层循环为什么 int i = gap;i<arr.length;i++,其实这就是一次序列的遍历。只不过是从第二组的第一个元素开始。
- 在for循环內的其他语句就是通过比较第j个和第j-gap个元素的大小,把较大值赋值给arr[j]。