InsertSort:(以升序为例)
插入排序的基本思想是:
每次将一个待排的记录,按照其关键字的大小,插入到前面已经排好序的有序区中适当的位置,直到全部记录插入完毕为止。
假设待排序的记录存放在数组R[0..n]中,初始时R[0]是一个有序区,R[1..n]是无序区,从i=1开始,依次将R[i]插入到有序区R[0..i-1]中,生成一个包含n个记录的有序区。
根据插入排序的思想,我们可以写出如下代码:
void InsertSort(int *arr , int len) { int i = 0; int j = 0; int tmp = 0; for (i = 1; i < len; i++) { tmp = arr[i]; for (j = i; j>0&&arr[j-1]>tmp; j--) //在有序区找到一个正确的位置 { arr[j] = arr[j - 1]; //将当前记录后移 } arr[j] = tmp; //将tmp插入到找到的位置 } }
优化:折半插入
既然有序区已经有序,那么我们在寻找合适位置的时候,可以使用折半查找的思想在有序区寻找这个位置。
代码如下:
void InsertSort(int *arr, int len) { int i = 0; int j = 0; int tmp = 0; int mid = 0; int k = 0; for (i = 1; i < len; i++) { tmp = arr[i]; int left = 0; int right = i - 1; mid = (left&right) + ((left^right) >> 1); //求取平均值,可以防止溢出 while(left<=right) //利用BinarySearch在有序区查找一个合适的位置 { if (arr[mid]>tmp) //这种情况下,tmp要插入的位置肯定小于等于mid { right = mid-1; k = mid; } else if (arr[mid] <=tmp) //这种情况下,tmp要插入的位置肯定大于mid { left = mid+1; k = mid+1; } mid = (left&right) + ((left^right) >> 1); } for (j = i; j>k; j--) //将这个位置向后的所有元素后移 { arr[j] = arr[j - 1]; } arr[k] = tmp; //将tmp放到这个位置 } }
注意:这种优化减少了在有序区比较的次数,但是并不减少元素
移动的次数。
时间: 2024-12-28 18:21:07