直接插入排序

基本思路

将一个记录插入到已经排好序的有序表中,得到一个新的、长度加一的有序表


使用的结构:

#define MAX 10

//排序所用的顺序表结构 
typedef struct
{
	int a[MAX+1];  //存储排序数组,a[0]用作临时变量  
	int length;    //记录顺序表的长度 
}Sqlist;

//交换 
void swap(Sqlist *L,int i,int j)
{
	int t=L->a[i];
	L->a[i]=L->a[j];
	L->a[j]=t;	
} 


算法:

void InsertSort(Sqlist *L)
{
	int i,j;
	for(i=2;i<=L->length;i++)    //i从2开始
	{
		if(L->a[i]<L->a[i-1])      //将L->a[i]插入有序序列 
		{
			L->a[0]=L->a[i];		//用a[0]存储a[i]的值 
			
			for(j=i-1;L->a[j]>L->a[0];j--)    //注意for循环的各种条件     
				L->a[j+1]=L->a[j];			//记录后移 
				
			L->a[j+1]=L->a[0];				//将a[i]插入到正确的位置 
		}	
	}	
} 

代码解析:

假设我们的参数L中length=6,a[6]={0,5,3,4,6,2},其中a[0]用作临时变量。

第4行代码的for循环i从2开始意为:我们假设a[1]=5已经是放好位置的元素,所以后面的操作本质上就是以a[1]为中心,插入到它的左边或者右边(较大的在右,较小的在左)

第6行代码,i=2,L->a[2]=3小于L->a[1]=5,故继续执行if内的语句

第8行代码,a[0]存储a[i]有两个作用,一个是作为第10行的for循环的终止条件,其二是便于第13行的a[i]的插入

第10行代码for循环就是一个个判断目前的元素a[i]的左边的元素是否大于目前的元素,若大于,则左边的这一个元素往右移动一个位置。一直往左边遍历,直到找到有元素小于目前的元素a[i]或者已经遍历完了第一个元素,此时退出循环

退出该循环后,下一条语句将a[i]插入到正确的序列位置

进行第二次外层for循环,此时经过上次循环后a[1]=3,a[2]=5。而后i=3,L->a[3]=4小于L->a[2]=5,故执行if内的语句,

结果是a[3]插入到a[1]于a[3]之间变成了a[2]

此后重复步骤......


复杂度

最好的情况下,主要是执行第6行的if语句比较,由于有序,每次的if都不成立故无元素的移动,时间复杂度O(n)

最坏的情况下,逆序表,比较次数:2+3+...+n=(n+2)(n-1)/2次

移动次数:(n+4)(n-1)/2次

平均比较和移动次数:(n^2)/4

综上,时间复杂度为O(n^2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值