插入排序算法

数据结构课程中的插入排序算法:本篇文章主要记录总结三种简单常见的插入排序算法(直接插入排序,折半插入排序,希尔排序)的基本思想和简单实现。

插入排序:

在排序算法中,数据结构课程中常见的三种插入排序算法是:直接插入排序,折半插入排序,希尔排序。插入排序算法的基本思想是:从给定的一个关键字序列中,每排序一趟就将一个待排序的元素,按照其关键字值的大小插入到已经排好序的部分文件中,直到全部值都插入完成,排序结束;其中,不同的插入排序方法,建立第一个排好序的部分文件的方法不同。插入排序与初始数据序列顺序有关,当初始序列越接近正序,性能越好。

下面依次介绍这三种插入排序:

1、直接插入排序

思想:最简单的排序方法,对于给定的一个关键字序列,将它的第一个元素作为一个排好序的部分文件,然后将后面的元素一个个的按照关键字大小插入到这个序列中,插入完毕之后排序结束;在指定元素插入到部分有序文件时,先对文件进行查找,找到元素应该插入的位置,然后将元素插入其中。

用C/C++实现的对含n个元素的一维数组的排序算法如下:

//直接插入排序
void InsertSort1(int a[],int n)
{
        int i,j,temp;
        //从第二个元素开始插入
        for(i=1;i<n;i++)
        {
                temp=a[i];
                j=i-1;
                //查找
                while(j>=0&&a[j]>temp)
                {
                        a[j+1]=a[j];
                        j--;
                }
                a[j+1]=temp; //插入
        }
}
对于直接插入排序:

 

2、折半插入排序

思想:折半插入排序的本质思想和直接插入排序别无二致,只是在折半插入排序中对于有序的部分文件进行的查找为折半查找(二分查找),而直接插入排序用的是顺序查找。

用C/C++实现的对含n个元素的一维数组的排序算法如下:

//折半插入排序
void InsertSort2(int a[],int n)
{
        int i,j,temp,low,mid,high;
        for(i=1;i<n;i++)
        {
                temp=a[i];
                low=0;
                high=i-1;

                //折半查找
                while(low<=high)
                {
                        mid=(low+high)/2;
                        if(a[mid]<temp)
                                low=mid+1;
                        else
                                high=mid-1;
                }
                //插入
                for(j=i-1;j>=high+1;j--)
                        a[j+1]=a[j];
                a[high+1]=temp;
        }
}
对于折半插入排序,从时间上看,仅仅是减少了关键字的比较次数,平均时间复杂度没有改变,相关性能和直接插入排序一样。

3、希尔排序

思想:希尔排序又称缩小增量排序法,它把给定的关键字序列的元素按照下标的增量d分组,对每组元素采用的还是直接插入排序,然后将增量逐渐减小,当d最终减小到1时,整个数据合成为一组,排序完成。

用C/C++实现的对含n个元素的一维数组的排序算法如下:

//希尔排序
void ShellSort(int a[],int n)
{
        int i,j,d,temp;//d为增量
        d=n/2;
        while(d>0)
        {
                //简单插入排序思想
                for(i=d;i<n;i++)
                {
                        temp=a[i];
                        j=i-d;
                        while(j>=0&&a[j]>temp)
                        {
                                a[j+d]=a[j];
                                j=j-d;
                        }
                        a[j+d]=temp;
                }
                d=d/2;
        }

}

对于希尔排序:正序时效率最高,反序时效率最低;核心还是简单插入排序,相关性能如下:

 最后关于算法的测试:

/*插入排序算法*/
#include <iostream>
using namespace std;

//直接插入排序
void InsertSort1(int a[],int n)
{
        int i,j,temp;
        //从第二个元素开始插入
        for(i=1;i<n;i++)
        {
                temp=a[i];
                j=i-1;
                //查找
                while(j>=0&&a[j]>temp)
                {
                        a[j+1]=a[j];
                        j--;
                }
                a[j+1]=temp; //插入
        }
}

//折半插入排序
void InsertSort2(int a[],int n)
{
        int i,j,temp,low,mid,high;
        for(i=1;i<n;i++)
        {
                temp=a[i];
                low=0;
                high=i-1;

                //折半查找
                while(low<=high)
                {
                        mid=(low+high)/2;
                        if(a[mid]<temp)
                                low=mid+1;
                        else
                                high=mid-1;
                }
                //插入
                for(j=i-1;j>=high+1;j--)
                        a[j+1]=a[j];
                a[high+1]=temp;
        }
}
//希尔排序
void ShellSort(int a[],int n)
{
        int i,j,d,temp;//d为增量
        d=n/2;
        while(d>0)
        {
                //简单插入排序思想
                for(i=d;i<n;i++)
                {
                        temp=a[i];
                        j=i-d;
                        while(j>=0&&a[j]>temp)
                        {
                                a[j+d]=a[j];
                                j=j-d;
                        }
                        a[j+d]=temp;
                }
                d=d/2;
        }

}

//测试主函数
int main()
{
        int a[10]={144,232,111,678,329,834,123,230,567,431};
        cout<<"排序之前的元素序列为:";
        for(int i=0;i<10;i++)
        {
                cout<<a[i]<<"  ";
        }
        cout<<endl;

        //InsertSort1(a,10);
        //InsertSort2(a,10);
        ShellSort(a,10);

        cout<<"排序之后的元素序列为:";
        for(int i=0;i<10;i++)
        {
                cout<<a[i]<<"  ";
        }
        cout<<endl;
}

运行结果如下:

总结:排序思想总结参考于《新编数据结构习题与解析》,算法全部是最简单的实现,之所以没有参看教课书籍是因为那些书中的内容太全面,但是并不一定通俗易懂;算法实现用Codeblocks编译器运行通过;看思想总是会有云里雾里,似懂非懂的感觉,但是结合实践之后,发现那些思想的总结真是珍品,句句在理。

写这篇文章用于记录学习,也希望对像我一样的初学者有用。


你可能感兴趣的:(插入排序)