插入排序与希尔排序

直接插入排序

思路:
将未排序的元素逐个插入到已排序的元素中,使其保持有序:

假设前i个元素有序(初始时默认第一个元素一定是有序的)
而后n-i个元素无序,那么从第n-i个元素开始逐个将无序元素插入到有序元素当中,并保持有序元素集仍保持有序,从而使有序元素集不断增加,使无序元素集不断减少,直到全部元素都保持有序为止。

#include <stdio.h>
#include <stdlib.h>

//插入排序
void InsertionSort(int array[],int length)//length为数组长度 
{
	int temp;
	int i,j,k;
	for(i=1;i<=length-1;i++)//将待排序的length-1个元素插入到有序的位置 
	{
		temp=array[i];
		for(j=i;j>0&&temp<array[j-1];j--)
		{
			array[j]=array[j-1];
		}
		array[j]=temp;
	}
 } 
 
 //主函数调用插入排序
 main()
 {
 	int i,j,k;
 	int array[6]={2,5,1,3,6,4};
 	InsertionSort(array,6);
 	for(i=0;i<6;i++)
 	{
 		printf("%d ",array[i]);
	 }
 	
  } 

稳定性:稳定排序

时间复杂度分析:
外层必然有一个长度为n的循环
此循环中嵌套一个循环
嵌套的循环每次最小为0,最大为i即当前外层循环次数
最坏时间复杂度为:
1+2+3+…+n-1 = n(n-1)/2
T(n)=O(n^2)

希尔排序

希尔排序是对直接插入排序的改进,因为在直接插入排序中,当待排序数列有序度越高时,直接插入排序的时间复杂度越小。
所以基于这样的一个事实,希尔排序的思路是先将原数组按一定间距分成多个子数组,对每一个子数组进行直接插入排序。之后再缩小该间距进行下一次排序,每一次排序后整体数组的有序性都将有所提高,直到当该间距缩减为1时对数组整体进行最后一次直接插入排序,此时待排序数组的有序性已经比较高了,所以最后一次直接插入排序的时间复杂度将大大减小。
在这里插入图片描述
图中可以看到在最终排序结果里,两个相同元素4的前后位置发生了交换,所以希尔排序是一种不稳定排序。

#include <stdio.h>
#include <stdlib.h>
//希尔排序 
ShellSort(int array[],int n)
{
	int i,j,k,gap,temp;
	for(gap=n/2;gap>0;gap/=2)
	{
		//直接插入排序 
		//----------------------- 
		for(i=gap;i<n;i++)//从gap位置开始将第i个数插入到合适的位置
		{
		   //因为后面要交换这个数的位置,所以先将该数暂存起来
			temp=array[i];
			//将这个数与其分组中前面的数逐个比较,如果该数小于前面的数,则交换它和组内前一个数的位置,否则或遍历到gap位置之前则结束本次插入
			for(j=i;j>=gap&&temp<array[j-gap];j-=gap)
			{
				array[j]=array[j-gap];
			}
			//将之前要插入的数插入到最终位置
			array[j]=temp;
		}
		//----------------------- 
	}
}
main()
{
	int array[10]={4,2,7,1,0,6,5,8,9,3};
	ShellSort(array,10);
	int i;
	for(i=0;i<10;i++)
	{
		printf("%d ",array[i]);
	}
}

稳定性: 不稳定排序
时间复杂度分析:
最坏时间复杂度:O(n^2)
n在特定范围内时:O(n^1.3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值