插入排序学习笔记及C语言代码实现

  • 学习笔记

首先,我们先理解“栈”的概念

栈,即 stack,有点类似于货箱,为什么这么说呢?请看下图:

它的存取方式完全是货箱的存储方法:LIFO ( Last In First Out )后进先出法;

就了解这么多,我们可以步入正题:Insertion Soct( 插入排序 )

 插入排序,就好像打扑克牌;开始的时候,左手是空的,右手抓牌;我们抓到第2张的时候,右手就开始插入;所以无论什么时候左手的牌总是有序的。

图中:S代表有序的序列,R则代表无序的序列,阴影部分则是需要插入的一个数,这便是一次插入。关于S的变化是往后移动了一格;开了一个偷、头,我们只要重复该步骤,就可以将R全部插入至S中,完成排序。

而,阴影部分移动的过程,就需要用到“栈”了。我们要将高于阴影部分的S一个一个拿出来,再将S放进去,最后将拿出来的都放进去。

关于插入排序的动态图可以去这个网址:http://www.atool.org/sort.ph

代码如下

  • 核心代码:

void Insertion_Sort(int Array[],int n)
{
	int i,j;
	for(i =1; i <n; i++)
	{
		int temp=Array[i];
		for ( j =i; j >0 && Array[j-1] >temp; --j)
		
			Array[j]=Array[j-1];
			a[j]=temp;	
	}
}
  • 具体样例

#include <stdio.h>
void Insertion_Sort(int Array[],int n)
{
	int i,j;
	for(i =1; i <n; i++)
	{
		int temp=Array[i];
		for ( j =i; j >0 && Array[j-1] >temp; --j)
		
			Array[j]=Array[j-1];
			Array[j]=temp;	
	}
}
int main()
{
	int Array[]={9,4,7,1,6,2,8,3,5};
	int n=sizeof(Array)/sizeof(int),i;
	Insertion_Sort( Array,n );
	for ( i=0; i <n; i++)
	{
		printf("%d ",Array[i]);
	}
	return 0;
}	
  • 运行截图:

  • 问题思索:

插入排序是需要一个转存通道的;就像抓牌,右手就是一个转存通道;那么请问:

(1)样例中数组,转存的次数是多少?

(2)一组未知的无序数组(假设有n个数),转存的次数最大值,最小值是多少?

  • 关于问题:

我们先考虑数组{3,2,1},3移动至左手,次数0+1;2移动至右手,3移动至牌堆顶,2移动至左手,次数0+1+1;3移动至右手,再移动至左手,次数0+1+1+1;1移动至右手,3移动至牌堆顶部,再2移动至牌堆顶部,次数0+1+1+1+1;2移动右手再左手,次数0+1+1+1+1+1;3移动至右手再左手,次数0+1+1+1+1+1+1=6。

通过上面这个简单的例子;可以发现,转存的次数,与数组里的数组的逆序对有关;数组{3,2,1}有三个逆序对      (3,2)(3,1)(2,1),三个逆序对,而有序数组{1,2,3}也需要转存3次;所以不难推测出

(转存次数)=(数的个数)+(逆序对数)

我们就先解决了问题(2)

最小值对应有序数组 ——即 n

最大值对应逆序数组——即 n+n-1+n-2+.....+1=n(n+1)/2

那么相对应的第一问也出来了,逆序对有19对,转存次数为28个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值