插入排序--直接插入排序

    插入排序的基本思想是:每次将一个待排序的元素插入到已排好序的子表的合适位置上。以下的排序都是按照增序进行排列。

一、插入排序思路

    1、假设待排序的元素存放在数组R[0 ...n-1]中,共n个待排元素。在排序的某一刻时, 有序区R[0 ...i-1],无序区R[i ...n-1]。i的初始值为1,即有序区中仅有一个元素R[0]。在该时刻,要做的是将无序区的第一个元素,即R[i]插入到有序区的合适位置,即插入到有序区R[0 ...i-1]。为了将R[i]插入有序区的合适位置,需要逐次和有序区元素比较,直到R[i]>=有序区的某元素停止。在比较过程中,满足R[i]<有序区元素的需要进行位置替换。

    直接插入排序的一趟操作是将当前无序区的第一个元素,插入到有序区R[0 ...i-1]的合适位置。然后R[0 ...i]成为新的有序区。


二、排序算法

/***********************************************************************
* FUNCTION:    直接插入排序
* AUTHOR:      zhuzi
* DATE:        2018-5-01
* VERSION:     v1.0
* NOTES:       
* MODIFICATION:
**********************************************************************/
#include <iostream>

using namespace std;

typedef int KeyType;
typedef int InfoType;

typedef struct 
{
    KeyType key;
    InfoType data;
}RecType;

/*********************************************************************
* function:        直接插入排序
* parameters:      RecType R[], 待排序数组
                   int n, 数组个数
* return value:    无
**********************************************************************/
void InsertSort1(RecType R[], int n)
{
    int i, j;
    RecType tmp;
    
    for(i = 1; i < n; i++)
    {
        tmp = R[i];
        j = i - 1;
        
        while((j >= 0) && (tmp.key < R[j].key) )//进入内循环,交换元素的条件
        {
            R[j+1] = R[j];
            j--;
        }
        R[j + 1] = tmp;
    }
}

/*********************************************************************
* function:        输出元素
* parameters:      RecType R[], 有序区数组
                   int n, 数组元素个数
* return value:    无
**********************************************************************/
void print(RecType R[], int n)
{
    for(int i = 0; i < n  ; i++)
    {
        cout << "R[" << i << "] <" << R[i].key << "," << R[i].data << ">" << endl;
    }
}

int main(int argc, char *argv[])
{
    RecType RT[] = {{1,11},{3,33},{2,22},{5,55},{7,77},{8,88}};

    InsertSort1(RT, sizeof(RT)/sizeof(RT[0]));

    print(RT, sizeof(RT)/sizeof(RT[0]) );
    
    return 0;
}

三、算法分析

    直接插入算法由两重循环构成,对于具有n个元素的表,外循环要进行n-1趟排序。每一趟排序中,仅当带插入元素R[i].key>=R[i-1].key时,才不会进入内循环,即不用进行元素移动。

    若初始数据为正序,则在每趟排序中比较一次,不会进入内循环,但会执行tmp = R[i]; R[j + 1] = tmp; 即移动两次。正序插入排序中,关键字比较次数为:n-1,元素移动次数为2(n-1)。

    若初始数据为逆序,则在每趟排序中需要比较i次,移动i+2次。逆序插入时,关键字比较次数为:n(n-1)/2 = O(n^2), 元素移动次数为:(n-1)(n-4)/2=O(n^2)。

    算法的平均复杂度是O(n^2),因为平均的比较次数为i/2, 平均的移动次数为i/2+2,故平均时间复杂度约为O(n^2)。(i/2+i/2+2)=(i+2)=(n-1)(n-4)/2=O(n^2)


猜你喜欢

转载自blog.csdn.net/zhuzitop/article/details/80155140