基本排序(1)——插入排序、希尔排序

目录

前言

插入排序

    直接插入排序:

    代码实现

    希尔排序

代码实现

以上代码解析:


前言

    排序算法有很多种,而且非常重要,以前常见的排序算法是冒泡排序,不过相比与冒牌排序,还有很多很好用,时间复杂度更低的排序算法。

插入排序

    直接插入排序:

        直接插入排序适用于比较有序的序列,序列越有序,时间复杂度越低。插入排序的实现是先指定一个空间用于存放临时数据,比如我们可以选用数组的第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退出,即可完成排序。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值