插入排序:直接插入排序,折半查找排序,希尔排序

本文介绍了三种排序算法——直接插入排序、折半插入排序和希尔排序,详细解释了每种算法的工作原理,并提供了C#语言实现代码。通过测试数据进行验证,展示了不同算法的时间复杂性和性能特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   该算法来源于[数据结构(C语言版)].严蔚敏_吴伟民.,这里根据自己需要换成了c#语言,有的不清楚,是在百度百科搜索后整理了一下,记录下来的,

   数组从[0..n-1]进行排序的

   测试数据:int[] array = { 49, 38, 65, 97, 76, 13, 27, 49 };

   1.直接插入排序

    /// <summary>
    /// 对数组array[0..n-1]进行直接插入排序
    /// 基本操作:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序
    /// 直接插入排序属于稳定的排序
    /// 时间复杂性为O(n^2),空间复杂度为O(1)
    /// </summary>
    public void InsertSort(int[] array)
    {
        int i, j, temp;
        for ( i = 1; i < array.Length; i++) //第二个记录开始比较
        {
            temp = array[i];                //temp 暂存array[i]
            for (j = i; j > 0 && temp < array[j - 1]; --j)// array[i]<array[i-1],需要将array[i]插入到有序列中
            {
                array[j] = array[j - 1];   //记录后移
            }
            array[j] = temp;               //插入正确位置                     
        }
    }
2.折半插入排序
    /// <summary>
    /// 折半插入排序算法是一种稳定的排序算法,比直接插入算法明显减少了关键字之间比较的次数,速度比直接插入排序算法快,但记录移动的次数没有变
    /// 时间复杂度为O(n^2),附加空间O(1)
    /// 具体操作:
    /// 在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high],
    /// 则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,
    /// 如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),
    /// 否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),
    /// 如此直至low<=high不成立,[2]即将此位置之后所有元素后移一位,并将新元素插入a[high+1]
    /// </summary>
    public void BinaryInsertSort(int[] array)
    {
        for (int i = 1; i < array.Length; i++)
        {
            int temp = array[i];
            int low = 0;
            int high = i - 1;
            while (low <= high)
            {
                int mid = (low + high) / 2; 
                if (temp < array[mid])  //比参考元素小,则选择a[low]到a[mid-1]为新的插入区域(即high=mid-1)
                {
                    high = mid - 1;
                }
                else
                {
                    low = mid + 1;
                }
            }
            for (int j = i; j >= low + 1; j--)
            {
                array[j] = array[j - 1];//记录后移
            }
            array[low] = temp;//插入位置
        }
    }

3.希尔排序

    /// <summary>     /// 希尔排序(插入排序)     /// 希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序     /// 基本思想     /// 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。     /// 先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组

   /// 中进行直接插入排序为止。

    /// 希尔排序是不稳定的     /// </summary>     /// <param name="array"></param>     /// <param name="dk"></param>     public void ShellInsert(int[] array, int dk)     {         int i, j, r0;

        for (i = dk; i < array.Length; ++i)         {             if (array[i] < array[i - dk]) //需将array[i]插入有序增量子表             {                 r0 = array[i]; //暂存

                for (j = i - dk; j >= 0 && r0 < array[j]; j -= dk) //j>=0 以防下标越界                     array[j + dk] = array[j]; //记录后移,查找插入位置

                array[j + dk] = r0; //插入array[i]到正确位置             }         }     }

 

2种增量的取值:

    /// <summary>     /// 按增量序列dlta[0..t-1]对顺序表array作希尔排序     /// 增量序列如:1,2,3,5,9,...     /// 算法:dlta[k]= 2的(t-k)次方 + 1, 0<=k<=t<=log2(n-1)取最小值

///int[] dlta = { 1,2,3,5,9};     /// </summary>     public void ShellSort(int[] array, int[] dlta)     {         for (int k = dlta.Length - 1; k >= 0; k--)             ShellInsert(array, dlta[k]);//一趟增量为dlta[k]的插入排序     }

    /// <summary>     /// 按增量序列 n=n/3+1 对顺序表array作希尔排序     /// </summary>

    public void ShellSort(int[] array)     {         int n = array.Length;//增量初值,这里测试取的数组的长度         do         {             n = n / 3 + 1; //求下一增量             ShellInsert(array, n);//一趟增量为n的shell插入排序         } while (n > 1);     }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值