有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——
插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,
时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的
数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
public class InsertSort {
public void sort(int[] array) {
for (int i = 1; i < array.length; i++) {
int tmp = array[i];
int j ;
for (j = i-1; j >=0; j--) {
if(array[j]>tmp)
{
array[j+1]= array[j];
}else{
break;
}
}
array[j+1] = tmp;
}
for (int num : array) {
System.out.println(num);
}
}
public static void main(String[] args) {
InsertSort insertSort = new InsertSort();
insertSort.sort(new int[] { 9, 4, 2, 6, 7, 3, 10, 33, 88, 1, 17,4,2 });
}
}
二分法插入排序
二分法插入排序是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上。
1、二分法查找插入位置
如果R<R[m]成立,那右
指针就要向左移动中间指针一位,否则,左指针要向右移动中间指针一位。反复查找,直到左指针大于右指针时停止。
2、后移,有点迷惑,什么时候需要后移呢?有哪些记录需要移动呢?
虽然我们很清楚的知道,我们需要后移那些排序码大于R的记录,但难免会问自己这样几个问题。其实它相当于需要移动从i-1到左指针的记录。
3、插入
由1中得到的左指针其实就是元素要插入的位置。
public class BinaryInsertSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a={49,38,65,97,176,213,227,49,78,34,78,38,12,164,11,18,1};
System.out.println("排序之前:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//二分插入排序
sort(a);
System.out.println();
System.out.println("排序之后:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}
private static void sort(int[] a) {
// TODO Auto-generated method stub
for (int i = 1; i < a.length; i++) {
int tmp = a[i];
int left= 0;
int right = i-1;
while (left<=right) {
int mid = (left+right)/2;
if(tmp > a[mid])
{
left = mid+1;
}else{
right = mid-1;
}
}
for (int j = i-1; j>= left; j--) {
a[j+1]=a[j];
}
if(left!=i){
//左位置插入该数据
a[left] = tmp;
}
}
}
}