内部排序算法1(插入排序)

内部排序算法1(插入排序)

重点指标
1. 排序算法的时间代价分析
2. 排序算法的空间代价分析
3. 排序方法的稳定性
4. 静态排序和动态排序
5. 算法的适用性

排序
1. 排序是对数据元素的逻辑顺序或者物理顺序的一种重新排列。
2. 排成非减(递增)顺序称为正序, 排成非增(递减)顺序称为逆序。
3. 排序的依据是排序码(可重复),即元素或记录中的用于作为排序依据的项。
4. 静态排序在排序过程中链表结构不变,可以避免数据移动,但是代价是增加了使用的指针空间。

排序算法的稳定性的判断原则
1. 如果需要把所有元素按排序的升序排列,在每趟从前向后比较选小时把排序码相等的视为更小者,或从后向前比较选大时把排序码相等的视为更大者,使得原本正序的元素视为逆序,一旦交换将导致两个排序码相等的元素发生相对位置的前后颠倒。
2. 在排序的过程中,需要以一个较大的间隔互换数据,或把数据隔空搬运一段较大距离时,排序方法一定不稳定,它可能会把原先排在前面的元素搬到具有相同排序码的另一个元素的后面,颠倒了具有相同排序码的不同元素的相对前后位置。
3. 不稳定的排序算法有4种:Shell排序、简单选择排序、快速排序和堆排序。
4. 稳定排序算法有 种,直接插入排序、折半插入排序、气泡排序、归并排序、锦标赛排序和基数排序。

排序算法的适用于那种数据结构(顺序结构和单链表结构)
1. 适用于顺序表的排序方法有:直接插入排序、折半插入排序、希尔排序、气泡排序、快速排序、简单选择排序、堆排序、归并排序、计数排序和奇偶排序等。
2. 适用于单链表的排序方法有:直接插入排序、气泡排序、简单选择排序、归并排序和基数排序。
3. 适用于树形排序的排序方法有:锦标赛排序(胜者树)、多路归并排序(败者树)、 二叉查找树排序、堆排序等。


排序算法的介绍

1. 插入排序

思路

将待排序的子序列中的一个元素按其排序码的大小插入到已经排好序的有序子序列中的适当位置,使得有序子序列扩大一个元素。如此继续,直到待排序子序列中的所有元素取空并都插入到有序子序列。

思想

把数组a[n]中待排序的n个元素看成一个有序表和一个无序表,开始时有序表中只包含一个元素a[0],无序表中包含有n-1个元素a[1]~a[n-1]。排序过程中每次从无序表中退成第一个元素,把它插入到有序表中的适当位置,使之成为新的有序表,这样经过n-1次退出和插入后,无序表就变成空表了,有序表中就包含了所有的元素。

图示


这里写图片描述
图片来自: 几种基本的插入排序

算法描述

//插入排序头文件
#pragma once
#include<iostream>
typedef int DataType;

class InsertSort
{
public:
    InsertSort(int length);
    void create();
    void sort();
    void print();

private:
    DataType *data;
    int len;
};

InsertSort::InsertSort(int length)
{
    len = length;
    data = new DataType[len];
}

inline void InsertSort::create()
{
    std::cout << "请输入要排序的序列: " << std::endl;
    for (int i = 0; i < len; i++)
    {
        int temp;
        std::cin >> temp;
        data[i] = temp;
    }
    std::cout << "输入完毕" << std::endl;
}

inline void InsertSort::sort()
{
    int i, j;
    for (i = 1; i < len; i++)
    {
        if (data[i] < data[i - 1])      //当序列放生逆序的时候才插入,否则跳过。
        {
            int temp = data[i];         //记录需要排序的那个值,然后从后往前比较并移动数据。
            for (j = i - 1; temp < data[j] && j >= 0; j--)
            {
                data[j + 1] = data[j];
            }
            data[j + 1] = temp;
        }
    }
}

inline void InsertSort::print()
{
    for (int i = 0; i < len; i++)
    {
        std::cout << data[i] << " ";
    }
    std::cout << std::endl;
}

main文件

//插入排序main文件
using namespace std;
#include"InsertSort.h"
int main() {
    InsertSort insertSort(10); //排序的序列中有十个元素
    insertSort.create();       //输入十个数
    insertSort.sort();         //排序
    insertSort.print();        //输出序列
    system("pause");
}

结果


这里写图片描述

算法分析

事件复杂度分析

每次在有序的子序列中从后往前寻找插入元素应该插入的位置。这种方式导致算法事件代价严重依赖于待排序的序列的初始排列。最好的情况下,当初始排列全部有序(从小到大)的情况下,每趟插入元素只需要和有序序列的最后一个元素作比较,并不需要移动,总的比较次数(KCN)为n-1次, 移动次数(RMN)为0次。 在最坏的情况下,即待排序元素的序列中所有元素已经从大到小排列(反序),若想将它们翻转过来,则第i个元素要和前面i-1个元素做比较,总的比较次数为1+2+…+(n-1) = (n-1)*n/2次。在每一次比较之后都需要移动一次,加上取出该元素和放入指定的位置两次,也就是 ni=0(i

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
直接插入排序是一种简单的内部排序算法,其基本思想是将待排序的数据分为两部分,一部分是已排好序的数据,另一部分是待排序的数据,然后将待排序的数据逐个插入到已排好序的数据中,直至所有数据都排好序为止。 在实现直接插入排序算法时,需要注意以下几点: 1. 数组下标的边界问题:在实现直接插入排序算法时,需要注意数组下标的边界问题,以免出现越界的情况。 2. 数据移动的效率问题:在实现直接插入排序算法时,需要注意数据移动的效率问题。每次插入一个数据时,需要将已排好序的数据逐个向后移动,这样会导致算法的时间复杂度增加。因此,可以采用一些优化策略,例如使用哨兵、减少数据移动等方式提高算法的效率。 3. 稳定性问题:直接插入排序算法是稳定的,也就是说,在排序过程中相同元素的相对位置不会发生改变。因此,在实现直接插入排序算法时,需要保证算法的稳定性,以便得到正确的排序结果。 4. 对数据的要求:直接插入排序算法适用于数据量比较小的情况,如果数据量较大,则需要采用其他更高效的排序算法。此外,直接插入排序算法对数据的要求比较宽松,不需要数据具有任何特殊的结构。 总之,在实现直接插入排序算法时,需要注重算法的细节,以便提高算法的效率和正确性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值