排序算法大全——插入排序
一、排序算法介绍 :
在计算机科学的世界里,排序无疑是最基础、最核心的议题之一。从数据库的高效查询,到搜索引擎对海量信息的整理,再到我们手机通讯录中按字母顺序排列的联系人,排序算法的身影无处不在。它就像一位无形的整理师,将杂乱无章的数据元素,按照某种特定的顺序(如数字大小、字母先后)重新排列,从而为后续的数据处理和分析奠定坚实的基础。那么,面对不同的场景,我们该如何选择合适的排序算法?它们背后又隐藏着怎样精妙的智慧与效率的博弈?本篇博客将带您深入探索排序算法的奇妙世界。
二、排序分类:
本篇博客主要是基于C语言来介绍一些内部排序算法大全包括:插入排序(直接插入排序、折半插入排序、希尔排序)、交换排序(冒泡排序、快速排序)、选择排序(简单选择排序、堆排序)、归并排序、基数排序。
而本篇博客主要讲解插入排序的过程及其对于算法代码
三、插入排序:
插入排序归根结底其实就是将一组要排序的数按照规则便利,每次便利后将比较完的数依次归纳到一个区间,而这个区间是由这些已经比较完的数组成的有序区间。
1、直接插入排序:
直接插入排序就是从前往后依次便利然后将便利的数组成一个有序序列的排序:
比如:3,1,0,9,23,11
第一趟:(1,3),0,9,23,11(比较3,1,此时1,3构成一个有序序列)
第二趟:(0,1,3),9,23,11(比0与有序序列,从0与3比较,再与1比较)
第三趟:(0,1,3,9),23,11
......
代码展示:
//插入排序的总体思想就是按顺序依次将每个数插入它前面的这个有序序列当中
//直接插入排序
void InsertSort(int a[], int n) {for (int i = 1; i < n; i++) {if (a[i] < a[i - 1]){int j = i - 1;//i-1是有序数据的第一个元素,比就是拿temp与j指向的元素开始比int temp = a[i];//将要插入的元素先放入一个临时变量中do {a[j + 1] = a[j];j--;} while (j >= 0 && temp < a[j]);//顺序不能变不然会奔溃a[j + 1] = temp;}}
}
这个代码有几个关键:
第一:比较时若是比有序序列最后一个数大,则不需要比较后面的数,直接插入到有序序列中,若是小则还需要继续往前比较其它数直到满足大于时候。
第二:因为首次比较后不需要再和这个数比较了所以使用do while函数比较好,可以直接与后面元素继续比较,少比较一次。
第三:插入不是简单的交换,而是将要插入位置之后所有元素后移一位再直接插入。
2、折半插入排序:
折半插入排序与直接插入排序的区别主要在于如何与有序序列比较,直接插入排序是依次与有序序列的元素按照顺序排序,而折半插入排序是利用折半也就是二分的思想来与要插入的数比较。
二分的思想:我们一般取中间一个数来比较(int mid = (left + right) / 2;)
比如:3,1,0,9,23,11
第一趟:(1,3),0,9,23,11
第二趟:(0,1,3),9,23,11(这次当中,第一次比较的是将0与1比较而不是和3,因为此时有序序列的下标为0和1,它折半向下取整就为第0位置,也就是数字1,很明显时间复杂度可能会减小)
第三趟:(0,1,3,9),23,11(此时先将9与1比较,再将9与3比较,比较两次,但是直接插入只需要比较一次,所以要是说折半插入排序一定比直接插入要好,这是个错误说法)
第四躺:(0,1,3,9,23),11
......
//折半插入排序
void BinaryinsertSort(int a[], int n)
{for (int i = 1; i < n; i++) {if (a[i] < a[i - 1]){int temp = a[i];int left = 0, right = i - 1;while (left <= right){int mid = (left + right) / 2;if (temp < a[mid])right = mid - 1;elseleft = mid + 1;}for (int j = i - 1; j >= left; j--) {a[j + 1] = a[j];}a[left] = temp;//此时left=right}}
}
3、希尔排序:
希尔排序它的思想主要是在遍历整个序列时候采用一种“差辈”的比,但是在区间内仍然是直接插入,也就是寻找一个每次要寻找的d,这个d一般是由表长的一半组成,然后比较下标为:
第一趟:d=表长/2
0,d,2d;
1,1+d,2+d;
2,2+d,3+d
...直到便利所有
第二趟:d=d/2
0,d,2d;
1,1+d,2+d;
2,2+d,3+d
.....
直到d=1时最后一趟排序完成
//希尔排序
void shellsort(int a[], int n)
{for (int d = n / 2; d >= 1; d /= 2) {for (int i = d; i < n; i++) //这里容易错要记住{if (a[i] < a[i - d]) {int j = i - d;int temp = a[i];do {a[j + d] = a[j];j -= d;} while (j >= 0 && temp < a[j]);a[j + d] = temp;}}}
}
