一、直接插入排序
它的思想:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
下面我来说一下我的思路:
1.第一趟比较前两个数,然后把第二个数按大小插入到有序表中。
2.第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中。
3.依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
下面我用图来帮助大家理解:
实现代码:
void InsertSort(int *arr, size_t size) { int end;//要排序的所有元素的最后一个元素的下标 int tmp; for (int i = 0; i < size - 1; i++) { end = i; tmp = arr[end + 1];//最后一个元素保存起来 //把所有大于最后一个元素的元素向后移动 while (arr[end]>tmp&&end >= 0) { arr[end + 1] = arr[end]; end--; } //把最后一个元素插入到不大于它的元素后面 arr[end + 1] = tmp; } }
二、希尔排序
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。
增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化,这个不少论文进行了研究,在此处就不再深究;本文采用首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;
下图详细讲解了一次希尔排序的过程:
代码实现:
void ShillSort(int *arr, size_t size) { int end;//要排序的所有元素的最后一个元素的下标 int gap = size / 2;//将数组分为size/2个子序列 int tmp;//临时值 for (gap = size / 2; gap > 0; gap /= 2)//增量递减 { for (int i = gap; i < size ; i++) { if (arr[i]<arr[i - gap]) { end = i - gap; tmp = arr[i]; //当arr[end]>tmp时,移动 while (arr[end]>tmp&&end >= 0) { arr[end + gap] = arr[end]; end -= gap; } arr[end + gap] = tmp; } } } }
希望大家能理解,写得不够好的地方,希望大家指出来。