排序算法---之插入排序(直接插入排序&希尔排序)

                                         排序算法--之插入排序

一、排序算法分为:

     1.插入排序(直接插入排序&希尔排序)

     2.交换排序(冒泡排序&快速排序)

     3.选择排序(直接选择排序&堆排序)

     4.归并排序

二、下面这张图对排序算法的时间复杂度&空间复杂度&稳定性做了一个总结:


二(1)、插入排序-----直接插入排序

1.算法代码(升序)

//直接插入排序
void InsertSort(int *a,size_t n)
{
	assert(a);
	for(size_t i=0;i<n-1;++i)
	{
		int end = i;//下标
		int tmp = a[end+1];//要插入的那个数
		while(end>=0)
		{
			if(a[end]>tmp)
			{
				a[end+1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}
		a[end+1] = tmp;//若最小的数在最后一个,end会--到-1,
	}
}
//测试代码
void PrintArray(int* a,size_t n)
{
	for(size_t i=0;i<n;++i)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//测试代码
void  InsertSortTest()
{
	int a[]={2,5,4,0,9,3,6,8,7,1};
	PrintArray(a,sizeof(a)/sizeof(a[0]));
	InsertSort(a,sizeof(a)/sizeof(a[0]));
	PrintArray(a,sizeof(a)/sizeof(a[0]));
}
2.算法时间复杂度

   最好的情况:正序(升序),for循环进行n次,(比较n次,不需要移动),时间复杂度为O(n).

   最坏的情况:   逆序,一个元素需要比较n次,总共有n个元素,时间复杂度为O(n^2).

    平均情况:   时间复杂度为O(n)

3.稳定性

 稳定性:就是有两个相同的元素,排序先后的相对位置是否变化,主要用在排序时有多个排序规则的情况下。

    直接插入是稳定的

二(2)、插入排序-----希尔排序

1.算法代码

//希尔插入,gap
void ShellSort(int* a,size_t n)
{
	assert(a);
	int gap = 3;
	while(gap>1)
	{
		gap = gap/3+1;//保证最后一次肯定是1
	    for(size_t i=0; i<n-gap; ++i)
	   {
           //单趟排序
		   int end = i;
		   int tmp = a[end + gap];
		   while(end>=0)
		   {
			   if(a[end]>tmp)
			   {
				   a[end+gap] = a[end];
				   end -= gap;
			   }
			   	else
					break;
		   }
		   a[end+gap] = tmp;//end会--到-3
		 
	   }
	}
}
//测试代码
void PrintArray(int* a,size_t n)
{
	for(size_t i=0;i<n;++i)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//测试代码
void ShellSortTest()
{
	int a[]={2,5,4,0,9,3,6,8,7,1};
	PrintArray(a,sizeof(a)/sizeof(a[0]));
	ShellSort(a,sizeof(a)/sizeof(a[0]));
	PrintArray(a,sizeof(a)/sizeof(a[0]));
}
2.算法时间复杂度

   最好的情况:由于希尔排序的好坏与gap有关,目前还没有计算出结果

   最坏的情况:时间复杂度为O(n*logn)

   平均情况:   时间复杂度为O(n*logn)

3、稳定性(看相同元素的位置

    希尔排序:不稳定

    由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值