zoukankan      html  css  js  c++  java
  • 数据结构与算法之美-排序(上)

    排序方法

    冒泡排序、插入排序、选择排序、快速排序、归并排序、计数排序、基数排序、桶排序。

    复杂度归类

    冒泡排序、插入排序、选择排序 O(n^2)

    快速排序、归并排序 O(nlogn)

    计数排序、基数排序、桶排序 O(n)

     

    算法的执行效率

    1. 最好、最坏、平均情况时间复杂度。

    2. 时间复杂度的系数、常数和低阶。

    3. 比较次数,交换(或移动)次数。

    排序算法的稳定性

    稳定性概念

    如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。

    稳定性重要性

    可针对对象的多种属性进行有优先级的排序。

    排序算法的内存损耗

    原地排序算法:特指空间复杂度是O(1)的排序算法。


    冒泡排序

    冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足就让它俩互换。

    稳定性

    冒泡排序是稳定的排序算法。

    空间复杂度

    冒泡排序是原地排序算法。

    时间复杂度

    最好情况:O(n)。

    最坏情况:O(n^2)。

    平均情况:平均时间复杂度为O(n^2)。

    C#代码实现

    public void BubbleSort(int[] data,int n)
    {
        if (n <= 1) return;//长度小于1的数组直接返回
        for(int j = 0; j < n; j++)//遍历数组
        {
            Boolean flag = false;//设标志位
            for (int i = 0; i < n-j-1; i++)//遍历数组未被排序的部分
            {
                if (data[i] > data[i + 1])//比较元素大小
                {
                    int temp = data[i];//交换数据
                    data[i] = data[i + 1];
                    data[i + 1] = temp;
                    flag = true;
                }
            }
            if (!flag) return;//如果一次冒泡无交换说明全部有序,返回
        }
    }

    插入排序

    插入排序将数组数据分成已排序区间和未排序区间。初始已排序区间只有一个元素,即数组第一个元素。

    在未排序区间取出一个元素插入到已排序区间的合适位置,直到未排序区间为空。

    稳定性

    插入排序是稳定的排序算法。

    空间复杂度

    插入排序是原地排序算法。

    时间复杂度

    1. 最好情况:O(n)。

    2. 最坏情况:O(n^2)。

    3. 平均情况:O(n^2)。

    C#代码实现

    public void InsertionSort(int[] data,int n)
    {
        if (n <= 1) return;
        for(int i = 1; i < n; i++)//遍历数组
        {
            int value = data[i];//记录要进行排序的第i个数组成员
            int j = i - 1;//从第i个数组成员前的成员开始遍历到头
            for (; j >= 0; --j)
            {
                if (data[j] > value)//如果其比第i个数组成员大,将其前移
                    data[j + 1] = data[j];
                else//否则就结束,因为前面的数据必然是有序的
                    break;
            }
            data[j + 1] = value;//在前移结束后停下的位置前插入记录的数据
        }
    }

    选择排序

    选择排序将数组分成已排序区间和未排序区间。初始已排序区间为空。

    每次从未排序区间中选出最小的元素插入已排序区间的末尾,直到未排序区间为空。

    稳定性

    选择排序不是稳定的排序算法。

    空间复杂度

    选择排序是原地排序算法。

    时间复杂度

    都是O(n^2))

    C#代码实现

    public static void SelectionSort(int[] data,int n)
    {
        if (n <= 1) return;
        for(int i = 0; i < n; i++)//遍历数组
        {
            int temp = data[i];//记录要排序的数组成员
            int pos = i;//记录最终的交换位置
            for(int j = i; j < n; j++)//遍历数组未交换的部分,找到最小的成员并记录其位置
            {
                if (data[j]<data[i])//如果未交换的部分比第i个成员小
                {
                    data[i] = data[j];//将其提到前面
                    pos = j;//记录交换的位置
                }
            }
            data[pos] = temp;//互换数据
        }
    }

    思考

    冒泡排序和插入排序的时间复杂度相同都是O(n^2),为什么插入排序比冒泡排序更受欢迎?

    因为冒泡排序的交换操作需要执行三次操作。

    如果数据存储在链表中,三种排序方法的时间复杂会变成怎样?

    假定只能改变节点位置

    冒泡排序,比较次数不变,因为指针,交换数据更加复杂。

    插入排序,比较次数不变,但可以直接插入数据,不需要一个个地后移数据。

    选择排序,比较次数不变,因为指针,交换数据更加复杂。

  • 相关阅读:
    npm, node, pm2 使用笔记
    没加证书的域名通过https访问,错误的访问到有证书的域名项目--已解决
    mysql数据库大表加索引
    上传大文件失败
    ifame 与父页面进行数据交互(跨域)
    windows平台编译PHP及扩展 和 踩过的坑
    vim 使用笔记
    git 在pull/push指定密钥文件
    记一次使用Xshell登陆提示所选用户密钥未在远程主机上注册
    学习网站与参考文档
  • 原文地址:https://www.cnblogs.com/errornull/p/9891343.html
Copyright © 2011-2022 走看看