美文网首页
排序_插入排序(直接插入排序&希尔排序)

排序_插入排序(直接插入排序&希尔排序)

作者: Mad_Elliot | 来源:发表于2019-02-22 11:32 被阅读0次

    插入排序基本思想:每步将一个待排序的对象,按其值的大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。

    直接插入排序:最简单的排序法!

    例子:


    代码实现:
    public static void SimpleInsertSort(int[] nums)
    {
        int temp, j;
        for (int i = 1; i < nums.Length; i++)//直接从第二个元素开始插入,直到最后一个元素
        {
            //获取待插入数据,腾出后移空间
            temp = nums[i];
    
            for (j = i - 1; j >= 0; j--)//从i位置前一个位置开始往前遍历
            {
                if (temp < nums[j])
                {
                    nums[j + 1] = nums[j];
                }
                else break;//因为前面数据已经有序,大于或等于直接退出循环即可
            }
    //while写法:
            //j = i - 1;
            //while (j > -1 && temp < nums[j])
            //{
            //    nums[j + 1] = nums[j];    //元素后移
            //    j--;
            //}
            nums[j + 1] = temp;//找到的j的位置的元素是比temp小的了,所以是插到j+1的位置
        }
    }
    

    总结:
    1、插入操作跟顺序表插入操作类似,元素需要后移。
    2、时间效率:O(n²)


    希尔排序:

    希尔排序:
    基本思想:
    把整个待排序的数据元素分成若干个小组,对同一小组内的数据元素用直接插入排序小组的个数逐次缩小,当完成了所有数据元素都在一个组内的排序后排序过程结束。

    例如:

    先步长为3,组内两个元素进行排序;
    再步长为2,两组,组内三个元素排序;
    最后步长为1,变成一组,所有元素一起排序。

    优点:
    前面排序的量少,速度快;
    后面因为前面的基础,序列基本有序,所以效率也高。

    算法实现:

    //increment:增值d
    public static void ShellSort(int[] nums, int increment)
    {
        int temp, j;
        //从该组第二个元素位置开始,即i = increment;i++即下一组的第二个元素位置
        for (int i = increment; i < nums.Length; i++)
        {
            temp = nums[i];//获取待插入元素,腾出后移空间
            
            for (j = i - increment; j >= 0; j -= increment)
            {   //组内往前遍历
                //组内前后两个元素相差increment个位置
                if (temp < nums[j])
                {
                    nums[j + increment] = nums[j];
                }
                else break;
            }
            nums[j + increment] = temp;
        }
        Console.Write("d = " + increment + "\n");
    }
    

    测试代码:

    //主函数
    static void Main(string[] args)
    { 
        int[] nums = { 256, 301, 751, 129, 937, 863, 742, 694, 76, 438 };
        ShowArray(nums2);
        Console.WriteLine("\n\nAfter Sort: ");
        ShellSort(nums, 5);
        ShowArray(nums);
        ShellSort(nums, 3);
        ShowArray(nums);
        ShellSort(nums, 1);
        ShowArray(nums);
    
        Console.ReadKey();
    }
    //遍历打印数组方法
    static void ShowArray(int[] nums)
    {
        foreach (var item in nums)
        {
            Console.Write(item + " ");
        }
        Console.WriteLine();
    }
    

    结果:


    总结:
    1、希尔排序是直接插入排序的改进版,实现代码细心点会发现,其实直接插入是间隔为1的插入排序,希尔排序是间隔为increment的插入排序。
    2、开始时d 的值较大,子序列中的对象较少,排序速度较快;随着排序进展,d 值逐渐变小,子序列中对象个数逐渐变多,由于前面工作的基础,大多数记录已基本有序,所以排序速度仍然很快。通常,d(i+1)=d(i) / 2 (结果取整)
    3、时间效率:O(n(log2n)²)

    因为通常d(i+1)=d(i) / 2 (结果取整),所以写希尔排序时,一般不需要传入增量值

    public static void ShellSort(int[] nums)
    {
        int temp, j, increment;
        for (increment = nums.Length / 2;increment > 0; increment = increment / 2)
        {
            //从该组第二个元素位置开始,即i = increment;i++即下一组的第二个元素位置
            for (int i = increment; i < nums.Length; i++)
            {
                temp = nums[i];//获取待插入元素,腾出后移空间
                for (j = i - increment; j >= 0; j -= increment)
                {   //组内往前遍历
                    //组内前后两个元素相差increment个位置
                    if (temp < nums[j])
                    {
                        nums[j + increment] = nums[j];
                    }
                    else break;
                }
                nums[j + increment] = temp;
            }       
        }            
    

    相关文章

      网友评论

          本文标题:排序_插入排序(直接插入排序&希尔排序)

          本文链接:https://www.haomeiwen.com/subject/osndyqtx.html