INSERTION_SORT(插入排序)

插入排序(算法导论):对于少量元素排序,它是一个有效的算法。插入排序的工作方式像许多人排序一手扑克牌一样。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。如图,左手的牌是排序好的,右手的牌是将要进行排序的。

                      

给算法的为代码:

INSERTION-SORT(A)                                 //假设输入一个有n个元素数组A[0....n-1]

        for j = 1 to A.length                             //找到A[1...n-1]个元素的正确位置

                key = A[j]                                   //key 为要插入的元素

                i = j - 1                                       // i 为要插入的元素的前一个元素位置

                while i > -1 and A[i] > key            // 前面有序的元素都比key大插在第一个,或者找到

                        A[i+1] = A[i]                        //比key小的插在其后面

                        i = i -1

                A[i+1] = key

该算法像是在要匹配的元素位置挖一个坑,把前面比它大的元素往后填,最后把key放在正确的坑位。

我们先假设一个混乱序列:

A[2]的插入方式跟上面情况相同,我们直接开始A[3]的排序

后面同理,直接上代码

#include<iostream>
using namespace std;

void INSERTION_SORT(int A[],int size)
{
	for (int j = 1; j < size; ++j)
	{
		int key = A[j];
		int i = j - 1;
		while (i > -1 && A[i] > key)
		{
			A[i + 1] = A[i];
			--i;
		}
		A[i + 1] = key;
	}
}
void Print(int A[],int size)
{

	for (int j = 0; j<size; ++j)
	{
		cout << A[j] << " ";
	}
	cout << endl;
}
int main()
{
	int A[] = { -2,3,5,1,7,3,11,14 };
	int size = sizeof(A) / sizeof(int); //我们在传递一个数组名作为函数实参时,我们还应该传入这个数组的长度,因为在函数内我们无法获取数组的长度(正确的字符串数组除外,因为正确的字符串数组最后一个总是'\0')
	Print(A,size);
	INSERTION_SORT(A,size);
	Print(A,size);
}
-2 3 5 1 7 3 11 14
-2 1 3 3 5 7 11 14

算法分析

假设A[0...n-1]第 i 行的每次执行需要的时间为 ci,t_{j}是对A[j]值插入时while循环执行的次数

循环语句要判断结束,所以总要多执行一次

 INSERTION-SORT(A)                                        代价                     次数

  0              for j = 1 to A.length                            c0                        n

  1                     key = A[j]                                   c1                        n-1

  2                      i = j - 1                                      c2                        n-1

  3                      while i > -1 and A[i] > key           c3                       \sum_{j=1}^{n-1}t_{j}

  4                              A[i+1] = A[i]                       c4                       \sum_{j=1}^{n-1}(t_{j}-1)

  5                              i = i -1                               c5        ​​​​​​​        ​​​​​​​       \sum_{j=1}^{n-1}(t_{j}-1)

  6                      A[i+1] = key                               c6                       n-1

综上

总的运行时间为:T(n)=c0*n+c1*(n-1)+c2*(n-1)+c3*\sum_{j=1}^{n-1}t_{j}+c4*\sum_{j=1}^{n-1}(t_{j}-1)+c5*\sum_{j=1}^{n-1}(t_{j}-1)+c6*(n-1)

最好的情况是输入的数组是有序的,此时每次插入只判断一次while不进入

则最佳的运行时间为:

T(n)=c0*n+c1*(n-1)+c2*(n-1)+c3*(n-1)+c6*(n-1)

=(c0+c1+c2+c3+c6)*n-(c1+c2+c3+c6)

最坏的情况是输入的数组是逆序的,此时t_{j}是对A[j]值插入时while循环执行的次数=j+1

\sum_{j=1}^{n-1}t_{j}=\sum_{j=1}^{n-1}(j+1)=\frac{n*(n+1)}{2}-1

while循环内

\sum_{j=1}^{n-1}(t_{j}-1)=\sum_{j=1}^{n-1}(j)=\frac{n*(n-1)}{2}

则最坏的运行时间为:

T(n)=

c0*n+c1*(n-1)+c2*(n-1)+c3*(\frac{n*(n+1)}{2}-1)+c4*(\frac{n*(n-1)}{2})+c5*(\frac{n*(n-1)}{2})+c6*(n-1)

=\frac{(c3+c4+c5)}{2}n^{2}+(c0+c1+c2+\frac{c3}{2}-\frac{c4}{2}-\frac{c5}{2}+c6)*n-(c1+c2+c3+c6)

插入排序的稳定性:

由于排完序后相同元素的前后位置没有发生改变,所以插入排序是稳定的排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值