排序算法(三)直接插入排序

一、直接插入排序算法

1、直接插入排序算法(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数加一的有序表;它属于一种插入排序的方法。

2、实现如下代码所示:

#include <stdio.h>

// 定义待排序记录类型
typedef int RecordType;

/**
 * 将待排序记录数组的下标i和下标j的两个记录进行交换
 */
void Swap(RecordType *rs, int i, int j)
{
    RecordType tmp = *(rs + i);
    *(rs + i) = *(rs + j);
    *(rs + j) = tmp;
}
/**
 * 打印待排序记录数组
 */
void PrintRs(RecordType rs[])
{
    int i, count = rs[0];

    for (i = 1; i <= count; i++)
    {
        printf("%d ", rs[i]);
    }
    printf("\n");
}

/**
 * 对记录列表进行直接插入排序
 */
void StraightInsertionSort(RecordType *rs)
{
    int i, j, count = rs[0];
    for (i = 2; i <= count; i++)
    {
        if (*(rs + i) < *(rs + i - 1))
        {
            *rs = *(rs + i);   // 用下标0的位置来保存当前记录
            for (j = i - 1; *(rs + j) > *rs; j--)  // 当j=1时,其实就指向了当前记录,是不可能大于自己的,所以这里的条件是不需要加上j >= 1判断的
            {
                *(rs + j + 1) = *(rs + j);
            }
            *(rs + j + 1) = *rs;
        }
    }
    *rs = count;   // 恢复下标0的元素为待排序记录个数
}

int main()
{
    RecordType rs[] = {5, 1, 5, 3, 2, 4};
    printf("排序前记录列表排序为:\t\t");
    PrintRs(rs);
    StraightInsertionSort(rs);
    printf("从小到大排序后,记录列表排序为:");
    PrintRs(rs);
    return 0;
}
3、时间复杂度

从空间复杂度角度看,它只需要一个记录的辅助空间(下标0的位置)。从时间复杂度角度看,最好的情况是要排序的记录列表本身就是有序的,那么只需要n - 1次比较而已,没有移动,时间复杂度为O(n);最坏情况是待排序列表是倒序排列的,此时需要比较2+3+...+n=(n+2)(n-1)/2次,而记录的移动次数是达到最大值3+4+...+(n+1)=(n+4)(n-1)/2次。所以如果排序记录是随机的,根据概率相同的原则,平均比较和移动次数均约为(n^2)/4次,所以直接插入排序算法的时间复杂度为O(n^2)。同样是O(n^2)的时间复杂度,直接插入排序算法比冒泡算法和简单选择排序算法的性能稍好一些。


参考书籍:《大话数据结构》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值