三种排序算法

本题要求实现一个函数,求N个集合元素A[ ]的中位数,即序列中第⌊N/2+1⌋大的元素。因为本题当N很大时,一些排序算法的运行时间过长,导致超时,所以我实验了三种算法包含:选择排序、直接插入排序、希尔排序。最终选择:希尔排序

1. 选择排序 -> O(n^2)

/*
*-----------选择排序---------
*基本思想:假设长度为N的数组A,要按照从小到大排序,
*那么先从N个数字中找到最小值min1,
*如果最小值min1的位置不在数组的最左端(也就是min1不等于A[0]),
*则将最小值min1和A[0]交换,接着在剩下的n-1个数字中找到最小值min2,
*如果最小值min2不等于A[1],则交换这两个数字,
*依次类推,直到数组A有序排列。
*--->算法的时间复杂度为O(n^2)<---
*/
ElementType Median(ElementType A[], int N)
{
    for (int i = 0; i < N; i++)
    {
        int index = i; //标记待排序列最左端
        for (int j = i+1; j < N; j++)
        {
            if (A[j] < A[index])
            {
                index = j; //遍历待排序列最小值,并标记位置
            }
        }
        if (index == i) //如果待排序列最小值为左端点,继续循环
            continue;
        else
        {
            float temp; //,否则,将最小值交换至最左端
            temp = A[index];
            A[index] = A[i];
            A[i] = temp;
        }
    }
        return A[N/2];
}

2. 直接插入排序 -> O(n^2)

/*
*--------直接插入排序---------
*基本思想:设数组为a[0…n-1]。
*1.初始时,a[0]自成1个有序区,无序区为a[1..n-1],令i从1开始计数。
*2.将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。
*3.i++并重复第二步直到i==n-1。排序完成。
*--->算法的时间复杂度为O(n^2)<---
*/
ElementType Median(ElementType A[], int N)
{
    int i, j;
    for (i = 1; i < N; i++)
        if (A[i] < A[i - 1])
        {
            float temp = A[i];
            for (j = i - 1; j >= 0 && A[j] > temp; j--) //定插入位置,并元素后移
                A[j + 1] = A[j];
            A[j + 1] = temp; //即A[j]=3 < A[i]=4时。如:3 5 4。4插入3和5之间。
        }
    return A[N/2];  
}

3. 希尔排序 -> O(n^(1.3~2))

/*
*-----------希尔排序-----------
*基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)
*分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)
*再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),
*效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
*--->算法的时间复杂度为O(n^(1.3—2))<---
*/
ElementType Median(ElementType A[], int N)
{
    int j, gap; //gap是步长,常规i++步长为1.
    for (gap = N / 2; gap > 0; gap /= 2)
    {
        for (j = gap; j < N; j++) //从数组第gap个元素开始
        {
            if (A[j] < A[j - gap]) //每个元素与自己组内的数据进行直接插入排序
            {
                float temp = A[j];
                int k = j - gap;
                while (k >= 0 && A[k] > temp) //定插入位置,并且数组元素后移
                {
                    A[k + gap] = A[k];
                    k -= gap;
                }
                A[k + gap] = temp; //元素插入
            }
        }
    }
    return A[N/2];
}

4. 参考来源

选择排序:https://blog.csdn.net/weixin_43728713/article/details/89145655
直接插入排序:https://blog.csdn.net/morewindows/article/details/6665714
希尔排序:https://blog.csdn.net/MoreWindows/article/details/6668714

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值