• 排序算法 之 插入排序


    本次介绍排序算法中的插入排序。

    1.直接插入排序:

    基本思想:

    直接插入排序也需要对待排序的序列在外层进行n-1次遍历,每次遍历时只把本次遍历次数处的元素和该元素之前的元素进行比较,来决定插入位置,并把从插入位置开始到该元素之前的所有元素后移,使从序列开始到该元素为止序列中的元素有序,直至遍历完成序列整体有序,插入排序算法的时间复杂度为O(n²);

    如下表格所示为待排序的序列:

    3 2 1 7 6 5 4 8 9

    当进行第一次遍历时把元素e[1]和e[0]作比较,e[1]<e[0],所以e[1]插入e[0]的位置e[0]元素后移,第一次遍历后序列中元素排列顺序如下:

    2 3 1 7 6 5 4 8 9

    当进行第二次遍历时把元素e[2]和e[0]、e[1]作比较,e[2]<e[0],所以e[2]插入e[0]的位置e[0]、e[1]元素后移,第二次便利后序列中元素排列顺序如下:

    1 2 3 7 6 5 4 8 9

    然后继续进行遍历,直至序列遍历完成…

    代码实现:

    /// <summary>
    /// 直接插入排序
    /// </summary>
    /// <param name="intArray"></param>
    /// <param name="length"></param>
    public static void InsertSort(int[] intArray, int length)
    {
        int i, j, k, temp, insertIndex;
        for (i = 1; i < length; i++)
        {
            insertIndex=0;
            temp = intArray[i];
            for (j = i - 1; j >= 0; j--)
            {
                if (temp > intArray[j])
                {
                    insertIndex = j+1;
                    break;
                }
            }
    
            if (insertIndex != i)
            {
                for (k = i; k > insertIndex; k--)
                {
                    intArray[k] = intArray[k - 1];
                }
                intArray[insertIndex] = temp;
            }
        }
    }

    2.改进的插入排序算法:

    在上面的插入排序算法中,我们先对本次排序中的元素进行循环比较找出插入位置,然后找出插入位置并把从插入位置处的元素进行后移,如果插入的位置不是元素本身的位置就多了元素后移操作,我们可以把元素比较和元素后移操作放在同一个循环中提高效率;

    代码实现:

    /// <summary>
    /// 直接插入排序优化1
    /// 在比较的同时移动元素
    /// </summary>
    /// <param name="intArray"></param>
    /// <param name="length"></param>
    public static void InsertSort1(int[] intArray, int length)
    {
        int i, j, temp, insertIndex;
        for (i = 1; i < length; i++)
        {
            if (intArray[i] < intArray[i - 1])
            {
                temp = intArray[i];
                insertIndex = i;
                for (j = i - 1; j >= 0 && temp < intArray[j]; j--)
                {
                    intArray[j + 1] = intArray[j];
                    insertIndex = j;
                }
                intArray[insertIndex] = temp;
            }
        }
    }

    3.折半插入排序:

    基本思想:

    折半插入排序外层遍历与直接插入排序外层遍历相同,不同的是每次遍历时把本次遍历次数处的元素与之前排序好的元素序列中间的元素作比较,如果小于中间的元素则把中间元素的前一个元素作为新的比较序列的末尾元素,待插入元素重新与新序列中间元素比较,如果大于中间元素则把中间元素的后一个元素作为新的比较序列的起始元素,待插入元素重新与新序列中间元素比较,直至新序列开始元素的位置大于结束元素的位置搜索结束,找出插入位置并移动元素,折半插入排序算法的时间复杂度仍为O(n²),但效率依然比直接插入排序高;

    代码实现:

    /// <summary>
    /// 折半插入算法
    /// </summary>
    /// <param name="intArray"></param>
    /// <param name="length"></param>
    public static void BinaryInsertSort(int[] intArray, int length)
    {
        int i, j, low, high, temp, middle;
        for (i = 1; i < length; i++)
        {
            temp = intArray[i];
            low = 0;
            high = i - 1;
            while (low <= high)
            {
                middle = (low + high) / 2;
                if (temp < intArray[middle])
                    high = middle - 1;
                else
                    low = middle + 1;
            }
            if (low != i)
            {
                for (j = i; j > low; j--)
                {
                    intArray[j] = intArray[j - 1];
                }
                intArray[low] = temp;
            }
        }
    }

    以上就是插入排序算法的内容。

  • 相关阅读:
    铁老大:不管你信不信,我是信了的NET代码版
    如何去掉字符串中的空格(转)
    DNN 社交挂件模块和DNN天气模块
    top、postop、scrolltop、scrollHeight、offsetHeight详解以及各浏览器显示效果差异
    vs2008视图菜单栏没有工具箱的解决办法
    DNN资源收集
    LINQ如何实现模糊查询
    Linq to excel
    前端各种出色的弹出层
    repo init 中指定manifest和branch的含义
  • 原文地址:https://www.cnblogs.com/liukemng/p/3716164.html
Copyright © 2020-2023  润新知