我是靠谱客的博主 直率鲜花,最近开发中收集的这篇文章主要介绍插入排序—直接插入排序(Straight Insertion Sort),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

插入排序—直接插入排序(Straight Insertion Sort)


    • 插入排序直接插入排序Straight Insertion Sort
      • 基本思想
      • 排序流程
      • 算法实现
      • 算法分析

1. 基本思想

将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
要点:设立哨兵,作为临时存储和判断数组边界之用。

2. 排序流程

这里写图片描述

3. 算法实现

代码

#include <stdio.h>

#define N 9
int arr[N]={9,8,7,6,5,4,3,2,1};
//int arr[N]={1,2,3,4,5,6,7,8,9};
//int arr[N]={4,1,5,7,9,3,2,8,6};
int step=0;
int nMove=0; /* 移动次数 */
int nFor=0; /* 循环次数 */
int nCompare=0; /* 比較次数 */

void print()
{
    int i;
    printf("No.%dt",step);
    for(i=0;i<N;i++)
        printf("%d ",arr[i]);
    printf("tnnFor:%2d  Move:%2d  nCompare:%2dn",nFor,nMove,nCompare);
}

void sort()
{
    int tmp,i,j;
    for(i=1;i<N;i++)
    {
        step++;
        nFor++;
        if(arr[i]<arr[i-1]) /* 如果第i个元素大于i-1元素,直接插入。否则,需要移动有序序列后插入 */
        {
            tmp=arr[i]; /* 复制为哨兵,存储待排序元素 */
            arr[i]=arr[i-1]; /* 第一次比较后确定需要后移 */
            nMove++;
            j=i-1;
            while(j>0 && tmp<arr[j-1])  /* 已经比较了第i-1个元素,循环从第i-2个开始比较,最差条件逆序比较到有序第一个arr[0] */
            {
                nCompare++;
                arr[j]=arr[j-1]; /* 元素后移 */
                nMove++;
                j--;
            }
            arr[j]=tmp; /* 在位置j插入第i个元素 */
        }
        nCompare++;
        print();
    }
}

void main()
{
    printf("Before...n");
    print();
    printf("Sorting...n");
    sort();
    printf("Sorted.n");
}

结果

Before...
No.0    9 8 7 6 5 4 3 2 1   nnFor: 0  Move: 0  nCompare: 0
Sorting...
No.1    8 9 7 6 5 4 3 2 1   nnFor: 1  Move: 1  nCompare: 1
No.2    7 8 9 6 5 4 3 2 1   nnFor: 2  Move: 3  nCompare: 3
No.3    6 7 8 9 5 4 3 2 1   nnFor: 3  Move: 6  nCompare: 6
No.4    5 6 7 8 9 4 3 2 1   nnFor: 4  Move:10  nCompare:10
No.5    4 5 6 7 8 9 3 2 1   nnFor: 5  Move:15  nCompare:15
No.6    3 4 5 6 7 8 9 2 1   nnFor: 6  Move:21  nCompare:21
No.7    2 3 4 5 6 7 8 9 1   nnFor: 7  Move:28  nCompare:28
No.8    1 2 3 4 5 6 7 8 9   nnFor: 8  Move:36  nCompare:36
Sorted.

4. 算法分析

  1. 当初始序列为正序时,只需外循环n-1次,每次进行一次比较且无需移动(交换)元素。此时比较次数(Cmin)和移动次数(Mmin)达到最小值。
    Cmin=n1
    Mmin=0
    此时时间复杂度为O(n)

  2. 当初始序列为反序时,需要外循环n-1次,每次排序中待插入的元素都要和[0,i-1]中的i个元素进行比较且要将这i个元素后移(arr[j] = arr[j-1]),i个元素后移总共i次,再加上tmp = arr[i]与arr[j] = tmp的两次移动,每趟移动的次数为i+2,此时比较次数(Cmin)和移动次数(Mmin)达到最大值。
    Cmax=1+2+...+(n1)=n(n1)/2=O(n2)
    Mmax=(1+2)+(2+2)+...+(n1+2)=(n1)(n+4)/2=O(n2)
    此时时间复杂度为O(n)

  3. 在直接插入排序中只使用了i、j、tmp这3个辅助元素,与问题规模无关,所以空间复杂度为O(1)。

  4. 相同元素的相对位置不变,如果碰见一个和插入元素相等的元素,那么插入元素把插入的元素放在相等元素的后面。所以相等元素的前后顺序没有改变。
    所以直接插入排序是一种稳定排序

最后

以上就是直率鲜花为你收集整理的插入排序—直接插入排序(Straight Insertion Sort)的全部内容,希望文章能够帮你解决插入排序—直接插入排序(Straight Insertion Sort)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部