zoukankan      html  css  js  c++  java
  • 排序算法——冒泡、选择、插入

    1、冒泡排序

    首先在n个数中,从前到后依次比较相邻的两个数,如果前一个数大于后一个数,则交换位置,这样下来可以将n个数中最大的数移动到最后的位置;然后在前n-1个数中,继续上述操作,将第二大的数移动到倒数第二个位置。这样重复n-1次,就可以得到一个从小到大的序列。冒泡排序可以是稳定的,当设置当两个数大小相同则不交换位置时,可以保持序列的稳定性。

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

    冒泡排序可以进行优化,这个优化还是蛮重要的,当在前i个数中都没有产生交换时,说明此时序列已经排好序了,那么可以直接break,如果知道是否产生了交换,我们可以设置一个flag,代码如下:

     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 < i; j++){
     5             if(q[j] > q[j+1]){
     6                 swap(q[j], q[j+1]);
     7                 flag = true;
     8             }
     9         }
    10         if(!flag) break;
    11     }
    12 }

    2、选择排序

    选择排序的思想是先在n个数中,选出一个最小的数,然后把它放到最前面,接着在剩下的数中,选出第二小的数,把它放到第二个位置,这样重复下去,直到所有的数都排好顺序。

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

    3、插入排序

    插入排序的过程像打牌,当摸到一张新牌后,要在现有的牌中找到一个合适的位置,将新牌插进去。摸到的第一张牌认为是已排好序的,再摸第二张牌的时候,就要比较与第一张的大小然后插入,重复这个操作,直到所有牌都是有序的。插入排序的时间复杂度最坏为O(n2),当给定的待排序的序列是由大到小给出的时候;最好为O(n),当给定的序列已经是排好序的时候。插入排序是稳定的,当遇到相同数的时候,将新牌插入到相同牌的前面,可以保证其稳定性。

    在插入排序中,我们将新牌由后往前进行比较,代码如下:

     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(q[j] > t){
     6                 q[j+1] = q[j];
     7             }
     8             else break;
     9         }
    10         q[j+1] = t;
    11     }
    12 }

    需要注意第10行的下标界限是j+1,界定的办法有两种,一个是如果第二个循环完整的执行完毕没有break,此时j为-1,所以第10行下标一定为j+1。另一种办法是假设新牌比所有牌都大,第二个循环根本没执行,那么新牌肯定是放在最后的位置了,也就是j+1的位置。

  • 相关阅读:
    1553: Good subsequence (很奇妙的set模拟题,也可以直接暴力)
    1550: Simple String (做得少的思维题,两个字符串能否组成另外一个字符串问题)
    1549: Navigition Problem (几何计算+模拟 细节较多)
    1548: Design road (思维题 做法:三分找极值)
    Python 正则表达式入门(初级篇)
    Python中的正则表达式教程
    软件自动化测试的学习步骤
    自动化测试的Selenium的python版安装与使用
    自动化测试一些问题
    自动化测试
  • 原文地址:https://www.cnblogs.com/hellosnow/p/11573823.html
Copyright © 2011-2022 走看看