• 算法 十大基本排序算法


    1. 优化冒泡排序 O(n2)

    算法描述:两两比较,将较小的数字置前,逐一替换;

    算法优化点:使用flag来判断是否使用了swap交换,若本身有序则直接break;

    算法分析:稳定,但慢,每次只能移动相邻两个数据。

    动图演示:

    冒泡排序

    代码:

     1 void bubble_sort(vector  <int> &q){
     2     for ( int i = q.size() - 1; i > 0; i --){
     3         bool flag = false;
     4         for ( int j = 0; j + 1 <= i; j ++)
     5             if ( q[j] > q[j + 1]){
     6                 swap(q[j], q[j + 1]);
     7                 flag = true;
     8             }
     9         if (!flag) break;
    10     }
    11 }

    2. 选择排序 O(n2)

    算法描述:从头开始,选择无序区最小的数置入有序区;

    算法分析:表现稳定,不占用额外内存空间,但比较次数多。

    动图演示:

    选择排序

    代码:

    1 void selection_sort(vector<int> &q){
    2     for ( int i = 0; i < q.size(); i ++)
    3         for ( int j = i + 1; j < q.size(); j ++){
    4             if (q[j] < q[i]) swap(q[j],q[i]);
    5         }
    6 }

    3. 插入排序 O(n2)

    算法描述:取出扫描元素与有序区比较,将小于数置后,按位移动;

    算法分析:稳定,快,但比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决。

    动图演示:

    代码:

     1 void insertion_sort(vector<int> &q){
     2     for ( int i = 1; i < q.size(); i ++){
     3         int t = q[i], j;
     4         for( j = i - 1; j >= 0; j --){
     5             if( t < q[j] ) q[j + 1] = q[j];
     6             else break;
     7         }
     8         q[j + 1] = t;
     9     }
    10  }

    4. 希尔排序 O(n1.3)

    算法描述:首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、 a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以次类推,在各组内用插入排序,然后取d'<d,重复上述操 作,直到d=1。

    算法分析:快,数据移动少,但不稳定,d的取值是多少,应取多少个不同的值,都无法确切直达,只能凭经验来取。

    动图演示:

    5. 归并排序 O(nlog2n)

    算法描述:将一个数组分为两部分,进行分别排序,后再相互比较,得出最终有序数组。

    算法分析:快,无论情况如何,时间复杂度均是O(nlog2n),但若数据节点数据量大,则不合适。

    动图演示:

    代码:

     1  void merge_sort(vector<int> &q, int l, int r){
     2     if (l >= r) return;
     3     
     4     int mid = (l + r) >> 1;
     5     merge_sort(q, l, mid);
     6     merge_sort(q, mid + 1, r);
     7     
     8     static vector<int> w;
     9     w.clear();
    10     
    11     int i = l, j = mid + 1;
    12     while (i <= mid && j <= r)
    13         if(q[i] <= q[j]) w.push_back(q[i ++]);
    14         else w.push_back(q[j ++]);
    15         
    16     while (i <= mid) w.push_back(q[i ++]);
    17     while (j <= r) w.push_back(q[j ++]);
    18     
    19     for(i = l, j = 0; j < w.size(); i ++, j ++) q[i] = w[j];
    20  }

    6. 快速排序 O(nlog2n)

    算法描述:选择一个基准,将较小的放置左边,大的放置右边,再使用递归把小雨的子数列和大于的子数列进行排序。

    算法分析:不稳定快,数据移动少,但不稳定

    动图演示:

    代码:

     1 void quick_sort(vector<int> &q, int l, int r){
     2      if (l >= r) return;
     3      int i = l - 1, j= r + 1, x = q[l + r >> 1];
     4      while(i < j){
     5          do j --; while (q[j] > x);
     6          do i ++; while (q[i] < x);
     7          if (i < j) swap(q[i],q[j]);
     8          else quick_sort(q, l, j), quick_sort(q, j + 1, r);
     9      }
    10  }

    7. 堆排序 O(nlog2n)

    算法描述:将初始待排序序列(R1,R2….Rn)构建成大顶堆,将堆顶元素R(1)与末尾元素R(n)交换,将其置入有序区,后再将新堆(R1,R2….Rn-1)调整为大顶堆,后再重复上述步骤,直至有序区元素个数为n-1.

    算法分析:不稳定,复杂。

    动图演示:

    8. 计数排序 O(n+k)

    算法描述:将无序数组中的每个数 i 都放入数组C[ i ]中,并对所有数字进行累加,后从数组中按序输出。

    算法分析:稳定,时间快。适用于k不是很大且比较集中。

    动图演示:

    9. 桶排序 O(n)

    算法描述:设置一个定量的数组当作空桶;便理输入数据,并发数据一个一个放入桶中,对每个非空桶进行排序,并完成拼接。

    算法分析:最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,显然,桶划分越小,各个桶之间的数据越少,排序越快,但相应的空间消耗会增大。

    图片演示:

    10. 基数排序 O(n+k)

    算法描述:先取得数组中的最大数,并取得位数,后使原始数组从最低位取每个位组成的radix数组,并对radix进行计数排序。

    算法分析:基数排序基于分别排序,分别收集,所以是稳定的。但基数排序的性能比桶排序要略差,每一次关键字的桶分配都需要O(n)的时间复杂度,而且分配之后得到新的关键字序列又需要O(n)的时间复杂度。假如待排数据可以分为d个关键字,则基数排序的时间复杂度将是O(d*2n) ,当然d要远远小于n,因此基本上还是线性级别的。基数排序的空间复杂度为O(n+k),其中k为桶的数量。一般来说n>>k,因此额外空间需要大概n个左右。

    动图演示:

    部分内容及动画演示参考:https://www.cnblogs.com/onepixel/articles/7674659.html

  • 相关阅读:
    织梦内容模型自定义字段设置一个随机数
    网页禁止右键查看源码屏蔽键盘事件
    面试官:如何防止 Java 源码被反编译?我竟然答不上来。。
    Elastic Job 同城主备、同城双活,高可用必备~
    再见,Spring Security OAuth!!
    怎么让 Linux 进程在后台运行?
    30 个 ElasticSearch 调优知识点,都给你整理好了!
    Spring Boot 2.5.4 发布,2.2.x 正式结束使命!
    移动端与服务器端之间的 token 怎么设计?
    最新数据库排行出炉,SQL Server 暴跌。。
  • 原文地址:https://www.cnblogs.com/john1015/p/12904858.html
Copyright © 2020-2023  润新知