2、插入排序(insertionSort)
a)插入排序分类: 插入排序主要做两件事,一是寻找插入点,二是移动插入点左侧的数据;所以根据插入点的不同我们将插入排序又分为直接插入排序、折半插入排序和二路插入排序。
b)直接插入排序(Straight Insertion Sort):
原理:我将依次遍历数组中的元素,将数组分为“使用中的”和“待使用中的”两部分,”在使用中的“数据时排序好的,“待使用中的”数据时未排序的,我们一个一个的将“待使用中的”数据插入到“使用中的”数据内。
算法示图:
数组序列: [2] 5 1 4 3 //一般我们将数组的第一个数作为“使用中的”部分
第一次排序:[2 5] 1 4 3 //2<5,无需进行插入
第二次排序:[2 1 5] 4 3 //5>1,将1插到5的前面
[1 2 5] 4 3 //2>1,将1插到2的前面
第三次排序:[1 2 4 5] 3 //5>4,将4插到5的前面
[1 2 4 5] 3 //2<4,无需进行插入
第四次排序:[1 2 4 3 5] //5>3,将3插到5的前面
[1 2 3 4 5] //4>3,将3插到4的前面
[1 2 3 4 5] //2<3,无需进行插入
代码实现:
观察外层循环排序了四次,而array.length=5,所以外层循环次数为array.length-1次;再观察内层循环,每次外层循环我们总是将“使用中”的部分与一个固定数(temp)作比较,比较顺序从“使用中”的部分的末尾开始到比temp小的数,设固定数的索引为i,则插入的条件为array[i-1]>temp,由此可见:
Public static void insertionSort(int[] array){
for(int i=1;i<array.length;i++){
int temp=array[i];
int j=0;
for(int j=i-1;(j>=0)&&( array[j]>temp);j--){
array[j+1]=array[j];
}
array[j+1]=temp;
}
}
c)、折半插入排序(binary insertion sort):折半插入排序其实是对直接插入排序的一种优化,和直接插入方法一样,折半插入排序也是从第二个元素开始比较,只不过插入“使用中”的部分时的方法采用了和二分查找算法,将temp与“使用中”部分的中间一个数进行比较,大于则往后继续二分,小于则往前二分。
public static void Insertion(int[] array){
int low,high,middle,key;
for(int i=1;i<array.length;i++){
key=array[i];
low=0;
high=i-1;
while(low<=high){
middle=(low+high)/2;
if(array[middle]>key)
high=middle-1;
else
low=middle+1;
}
for(int j=i-1;j>=low;j--){
array[j+1]=array[j];
}
array[low]=key;
}
}