zoukankan      html  css  js  c++  java
  • 排序算法的c++实现——冒泡排序

    冒泡排序

    冒泡排序是我们大多数人接触到的第一种排序算法,原理简单易懂,不多解释。说明三点:

    1. 冒泡排序是稳定排序,只有当两个元素不同时才会交换;

    2. 冒泡排序是原址排序,不需要借助额外的空间;

    3. 冒泡排序通常见到的都是通过循环来实现的,其实通过递归来实现更简洁。

    4. 冒泡排序的时间复杂度为O(N*N)

    代码如下所示:

      1 /***********************************************************************
      2 *   Copyright (C) 2019  Yinheyi. <chinayinheyi@163.com>
      3 *   
      4 * This program is free software; you can redistribute it and/or modify it under the terms
      5 * of the GNU General Public License as published by the Free Software Foundation; either 
      6 * version 2 of the License, or (at your option) any later version.
      7 
      8 *   Brief:    
      9 *   Author: yinheyi
     10 *   Email: chinayinheyi@163.com
     11 *   Version: 1.0
     12 *   Created Time: 2019年05月08日 星期三 21时53分25秒
     13 *   Modifed Time: 2019年05月08日 星期三 23时48分18秒
     14 *   Blog: http://www.cnblogs.com/yinheyi
     15 *   Github: https://github.com/yinheyi
     16 *   
     17 ***********************************************************************/
     18 
     19 
     20 // 对于冒泡排序,这肯定是大家接触编程时第一个碰到的排序算法。
     21 // 原理很简单: 以从小到大排序为例,假设一个数组的长度为n, 则:
     22 // 第一次: 从数组尾部开始向前, 两两元素之间进行比较, 共比较n-1次,就可以把最小元素移
     23 // 动到数组下标为0的地方, 此时有1个排序完成, 剩余n-1个还没有排序。
     24 // 第二次:还是从数组尾部开始向前,两两元素之间进行比较, 共比较n-2次,就可以把剩余的
     25 // 元素中最小的元素移动到数组下标为1的地方,此时有2个元素排序完成,剩余n-2还没有排序。
     26 // 第三次: 重复以上过程。
     27 //
     28 //    原始          第一次       第二次        第三次      第四次      第五次
     29 //     3             -12          -12           -12         ...         ...
     30 //     2              3            1             1
     31 //     8              2            3             1
     32 //     1              8            2             3
     33 //    -12             1            8             2
     34 //     32             1            1             8
     35 //     1              32           32           32
     36 //
     37 //
     38 // 说明:1. 冒泡排序是稳定排序,只有当两个元素不同时才会交换;
     39 //       2. 冒泡排序通常见到的都是通过循环来实现的,其实通过递归来实现更简洁。 
     40 //       3. 冒泡排序的时间复杂度为O(N*N)
     41 //
     42 //
     43 bool less(int lhs, int rhs);
     44 bool greate(int lhs, int rhs);
     45 static inline void swap(int& lhs, int & rhs);
     46 void PrintArray(int array[], int nLength_);
     47 typedef bool (*Comp)(int, int);
     48 
     49 //  基于循环来实现的冒泡排序:
     50 void BubbleSort_Loop(int array[], int nLength_, Comp CompFunc)
     51 {
     52     if (array == nullptr || nLength_ <= 1 || CompFunc == nullptr)
     53         return;
     54 
     55     // 对于n个元素,只需要排前n-1个元素即可, 即下标为0, 1, 2, ..., n-2的元素。
     56     for (int i = 0; i < nLength_ - 1; ++i)
     57     {   
     58         // 如果要使下标为i的元素变成有序的,需要从数组尾部开始两两交换,直至交换到i
     59         for (int j = nLength_ - 1; j > i; --j)
     60         {
     61             if (!CompFunc(array[j-1], array[j]))
     62             {
     63                 swap(array[j-1], array[j]);
     64             }
     65         }
     66     }   
     67 }
     68 
     69 // 基于递归来实现冒泡排序:
     70 void BubbleSort_Recursion(int array[], int nLength_, Comp CompFunc)
     71 {
     72     if (array == nullptr || nLength_ <= 1 || CompFunc == nullptr)
     73         return;
     74 
     75     // 从数组尾部向前,对不符合要求的元素进行两两交换,从而使数组头部的元素为最小或最大
     76     for (int i = nLength_ - 1; i > 0;  --i)
     77     {
     78         if (!CompFunc(array[i-1], array[i]))
     79         {
     80             swap(array[i-1], array[i]);
     81         }
     82     }
     83 
     84     // 对数组剩余的元素进行递归操作
     85     BubbleSort_Recursion(array + 1, nLength_ - 1, CompFunc);
     86 }
     87 
     88 // 小小的测试
     89 #include <iostream>
     90 /***************    main.c     *********************/
     91 int main(int argc, char* argv[])
     92 {
     93     int test1[10] = {-1, -23, 33, 423, -2349, 1, 1, 0, 9, 10};
     94     std::cout << "原顺序为:" << std::endl;
     95     PrintArray(test1, 10);
     96 
     97     std::cout << "基于循环的从小到大排序:" << std::endl;
     98     BubbleSort_Loop(test1, 10, less);
     99     PrintArray(test1, 10);
    100     std::cout << "基于循环的从大到小排序:" << std::endl;
    101     BubbleSort_Loop(test1, 10, greate);
    102     PrintArray(test1, 10);
    103 
    104     std::cout << "基于递归的从小到大排序:" << std::endl;
    105     BubbleSort_Recursion(test1, 10, less);
    106     PrintArray(test1, 10);
    107     std::cout << "基于递归的从大到小排序:" << std::endl;
    108     BubbleSort_Recursion(test1, 10, greate);
    109     PrintArray(test1, 10);
    110 
    111     return 0;
    112 }
    113 
    114 // 小于比较函数
    115 bool less(int lhs, int rhs)
    116 {
    117     return lhs < rhs;
    118 }
    119 
    120 // 大于比较函数
    121 bool greate(int lhs, int rhs)
    122 {
    123     return lhs > rhs;
    124 }
    125 
    126 // 交换两个元素的值
    127 static inline void swap(int& lhs, int & rhs)
    128 {
    129     int _nTemp = lhs;
    130     lhs = rhs;
    131     rhs = _nTemp;
    132 }
    133 
    134 // 打印数组函数
    135 void PrintArray(int array[], int nLength_)
    136 {
    137     if (nullptr == array || nLength_ <= 0)
    138         return;
    139 
    140     for (int i = 0; i < nLength_; ++i)
    141     {
    142         std::cout << array[i] << " ";
    143     }
    144 
    145     std::cout << std::endl;
    146 }
  • 相关阅读:
    mxd与service的关系
    转到不同磁盘
    通过vs命令提示符注册dll
    粘贴带有行号的代码到vs2010中
    添加本地图层出现要求cross domain policy的错误
    删除服务后添加相同名字的服务注意点
    Silverlight_F5调试时要求安装相应版本的运行时
    网页优化
    SqlBulkCopy快速批量大数据插入
    2012项目总结
  • 原文地址:https://www.cnblogs.com/yinheyi/p/10833785.html
Copyright © 2011-2022 走看看