目录
前言
排序算法有很多种,而且非常重要,以前常见的排序算法是冒泡排序,不过相比与冒牌排序,还有很多很好用,时间复杂度更低的排序算法。
插入排序
直接插入排序:
直接插入排序适用于比较有序的序列,序列越有序,时间复杂度越低。插入排序的实现是先指定一个空间用于存放临时数据,比如我们可以选用数组的第0号位作为临时空间,然后向后判断是否是升序,如果是升序则不用管,如果遇到第一个降序的元素则将这个元素存放到临时空间,再从这个元素的原位置处向前比较,遇到比这个元素大的就和他交换。
比如以下数组,可以看到 1 2 3 5 是升序,4是第一个降序的元素,将4存放到0号位。
然后向前比较,遇到5比4大,则这两元素交换位置。
最后再重复以上步骤即可完成排序,可以很容易看出,待排序序列的有序性会影响该方法的效率,序列越有序效率越高,其时间复杂度在O(N)~O(N^2)之间。
代码实现
void insert_sort(int *a, int len)
{
int i;
int j;
for (i = 2; i<len; i++) //下标从2开始,因为0号位是临时空间
{
if (a[i]<a[i - 1])//如果是升序排序,当前元素小于前一位元素时
{
a[0] = a[i]; //将当前元素存入临时空间
for (j = i - 1; a[0]<a[j]; j--)//逐渐向前比较,遇到大于临时空间元素时
{
a[j + 1] = a[j];//交换
}
a[j + 1] = a[0];
}
}
}
希尔排序
希尔排序相比于具有一定优势,希尔排序的核心思想是先定义一个步长,如果按照这个步长间隔将原序列划分为多个序列,然后分别排序这些序列,使整个序列局部有序,然后重复以上步骤,当整个序列趋于有序时就采用直接插入排序。
比如将以下序列按2为步长进行分割,分成两个组,分别排序每个组使其组内有序
代码实现
void ShellSort(int* a, int n){ //n为数组长度
int i, tem,gap,j,k;//gap为步长,
for (gap = n / 2; gap > 0;gap/=2){
for (int i = 0; i < gap; ++i){
for (j = i + gap; j < n; j += gap){
tem = a[j];
k = j - gap;
while (k >= 0 && a[k] > tem){
a[k + gap] = a[k];
k -= gap;
}
a[k + gap] = tem;
}
}
}
}
以上代码解析:
数列以 1 4 3 5 0 6 9 7 为例,首先gap(步长)为数组长度的一 半,将数组分成了4个小组,分别对这4个组排序:
第一趟结束后,gap自身除以2,步长减半,再次重复以上步骤知道最后gap小于0退出,即可完成排序。