排序

#####本文借鉴《我的第一本算法书》,算是对自己学习的总结,也希望分享下所学知识~~

1.冒泡排序
从某个方向(最右边)开始比较两个数字,把小的放在前面,一轮下来 小的就在最前面了
重复这个操作直到只剩最后两个数比较,然后完毕

第一轮n-1,第二轮n-2…第n-1轮1次
所以总的比较次数 = n-1 + n-2 + … +1 = n^2/2
如果恰好是从小到大就不要任何交换,如果桥好事反过来,每次都交换
时间复杂度为O(n^2)

static void BubbleSort(int[] a)
{
    for (int i = 0; i < a.Length - 1; i++)
    {
        for (int j = 0; j < a.Length - 1 - i; j++)
        {
            if (a[j] > a[j + 1])
            {
                int tmp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = tmp;
            }
        }
    }
}

2.选择排序
从最左端 找一个最小的数字放到首位
从第二个 找到最小的数字放到第二位
……
直到排序完成
和冒泡一样都是O(n^2)

static void SelectSort(int[] a)
{
    for (int i = 0; i < a.Length - 1; i++)
    {
        int minIdx = i;
        for (int j = i + 1; j < a.Length; j++)
        {
            if (a[j] < a[i])
            {
                minIdx = j;
            }
        }

        if (minIdx != i)
        {
            int tmp = a[i];
            a[i] = a[minIdx];
            a[minIdx] = tmp;
        }
    }
}

3.插入排序
假定第一个数的位置是正确的
用第二个数字比较,如果大就放在后面小的放在前面
用第三个数字比较,放在前两个正确序列里面
……
直到排序完成
如果左边的数字比当前小,就需要进行比较,最坏情况第n轮需要比较n-1次
如果比左边数字大就不需要比较
时间复杂度也为O(n^2)

static void InsertSort(int[] a)
{
    for (int i = 1; i < a.Length; i++)
    {
        int j = i;
        while (j > 0 && a[j] < a[j - 1])
        {
            int tmp = a[j];
            a[j] = a[j - 1];
            a[j - 1] = tmp;
            j--;
        }
    }
}

4.堆排序
构建堆 将n个数据存到堆内 复杂度为O(nlogn)
插入一个数据所需要的时间为O(logn)
每轮取出顶数据并且重构 所需的时间为 O(logn) 总共有n轮 为O(nlogn)
整体时间复杂度为 O(nlogn)


5.归并排序
对半分割,直到只剩下一个,然后两两合并
多个合并的时候比较首位
直到所有数字合并为一个整体

分割序列花费的时间不算在运行时间
合并只需重复比较首位数据大小,移动较小的数据
因此只需花费 两个子序列长度相应的运行时间
每行运行的时间为O(n) 分成log2n行
总运行时间为O(nlogn)


6.快速排序
找到一个基准数 小的放在前面 大的放在后面
然后再对 前后的两个序列进行 这种方法的排序
是一种分治法。将原本的问题分成两个子问题,通过递归

若每次选择的基准值都能使得两个子序列的长度为原来的一般 和归并排序一样 都为 O(nlogn)
分割了 logn 每一行都需要比较n次 所以为nlogn
如果运气不好每次都选择最小值未基准值,每次都需要把其他数据移动到右边,递归执行n行,时间复杂度O(n^2)
就相当于每次选择最小值并把它移动到了左边,就和选择排序一样了
平均时间为 O(nlogn)

static void QuickSort(int[] a, int start, int end)
{
    if (start >= end)
        return;

    int i = start;
    int j = end;
    int k = a[start];

    while (i < j)
    {
        while (i < j && a[j] > k)
            j--;
        while (i < j && a[i] < k)
            i++;

        if (i < j)
        {
            int tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;
        }
    }
    a[i] = k;

    QuickSort(a, start, i - 1);
    QuickSort(a, j + 1, end);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值