直接插入排序

直接插入排序是稳定的排序算法。

1、直接插入排序的基本思想:

假设待排序的记录存放在数组R[1...n]中。初始化,R[1]自成一个有序区,无序区为R[2...n]。从i=2起直至i=n为止,一次将R[i]插入当前的有序区R[1...i-1]中,生成含n个记录的有序区。

第i-1趟直接插入排序:

通常将一个记录R[i](i=2,...,n-1)插入到当前的有序区,是的插入后仍保证该区间里的记录是按关键字有序的操作,成为第i-1趟直接插入排序。

排序过程的某一中间时刻,R被划分成两个子区间:R[1...i-1](已排好序的有序区)和R[i...n](当前为排序的部分,可称为无序区)。

直接插入排序的基本操作是将当前无序区的第1个记录R[i]插入到有序区R[1...i-1]中适当的位置上,使R[1...i]变为新的有序区。因为这种方法每次使有序区增加1个记录,通常称为增量法。

插入排序与打扑克时整理手上的牌非常类似。没来的第一张牌无需整理,此后每次从桌上的牌(无序区)中摸最上面的1张并插入左手的牌(无序区)中正确的位置上。为了而找到这个正确的位置,须自左向右(或者自右向左)将没来的牌与做手中已有的牌逐一比较。

2、思想:

如下图所示,每次选择一个元素n插入到之前已排好序的部分R[1…i]中,插入过程中n依次由后向前与R[1…i]中的元素进行比较。若发现发现R[x]>=n,则将n插入到R[x]的后面,插入前需要移动元素。



3、算法时间复杂度

最好的情况下:正序有序(从小到大),这样只需要比较n次,不需要移动。因此时间复杂度为O(n)

最坏的情况下:逆序有序,这样每一个元素就需要比较n次,共有n个元素,因此实际复杂度为O(n­2)

平均情况下:O(n­2)
4、稳定性。  
     理解性记忆比死记硬背要好。因此,我们来分析下。稳定性,就是有两个相同的元素,排序先后的相对位置是否变化,主要用在排序时有多个排序规则的情况下。在插入排序中,
n1是已排序部分中的元素,当n2和n1比较时,直接插到n1的后面(没有必要插到n1的前面,这样做还需要移动!!),因此,插入排序是稳定的。

5、代码实现:

//编程实现直接插入排序
//1、每次插入排序,取的都是有序区后面的元素(无序区第一个元素)与前面有序区元素一一比较
//2、所以外层循环范围为1~n-1,内层循环起始条件为i-1,终止条件为j>=0(到头)同时是无序区元素<有序区(无序区元素找到位置)

//理解直接插入排序:
//开始时前面的一个数据当做有序区中的一个数据,暂存下标为i的数,下标从1开始
#include<iostream>
using namespace std;

//直接插入排序
static void insert_sort(int a[], int n)
{
	int i,j,temp;
	for (i = 1; i < n; i++)		//需要选择n-1次:这里a[i]选取的是有序区后面的数据,开始条件从1到最后
	{
		temp = a[i];		//用于存放无序区元素,因为每次都是从有序区向后挪移一个位置,所以无序区元素会被覆盖
		for (j = i - 1; j >= 0 && temp < a[j]; j--)		//如果满足条件就往后移挪:
		{				//最坏情况是temp比a[0]小,它要放在最前面,内层循环终止条件是j<0
				<span style="white-space:pre">		</span>//一般情况是当无序区中的数据大于有序区中的数据,内层循环终止条件是temp>a[j]
			a[j + 1] = a[j];	//把前面的数据写到后面的位置上:j=i-1,所以j+1=i,a[j+1]=temp=a[i],temp为中间变量			
		}
		a[j + 1] = temp;		//找到a[j]>temp的位置,j+1位置为temp的位置
	}
}

static void print_array(int a[], int len)
{
	for (int i = 0; i < len; i++)		//循环打印出数组的每一个元素
		cout << a[i] << " ";
}

void main9mianshiti1()
{
	int a[] = { 7, 3, 5, 8, 9, 1, 2, 4, 6 };
	cout << "before insert sort: ";
	print_array(a, 9);
	insert_sort(a, 9);		//直接进行插入排序
	cout << "\nafter insert sort: ";
	print_array(a, 9);
	system("pause");
}

6、测试效果:

before insert sort:7 3 5 8 9 1 2 4 6

after insert sort:1 2 3 4 5 6 7 8 9


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值