排序问题之冒泡排序

排序问题

算法问题的基础问题之一,便是排序问题:

  输入:n个数的一个序列,<a1, a2,..., an>。

  输出:一个排列<a1',a2', ... , an'>,满足a1' ≤ a2' ≤... ≤ an' 。(输出亦可为降序,左边给出的例子为升序)

一.算法描述

      这是一个非常常见的排序算法,可能在每一个人学习排序算法的过程中,第一个接触到的就是冒泡排序,因为十分简单易懂。冒泡排序一种流行但低效的排序算法,在排序的过程中反复交换相邻的未按次序排列的元素,每一趟的遍历过程中将最小的元素换到序列的最前面,经过n次遍历完成排序。当然你也可以选择将最大的元素放到序列的前面去构建降序序列,或者将最大元素放到最后来构建升序序列,都不会改变算法的本质。就像啤酒中密度较小的空气泡会浮到最上方一样,冒泡排序会让最小的值排到最前面。

      下面我们给出一个对序列[5, 2, 4, 6, 1, 3]使用冒泡排序得到递增序列的过程,在图中蓝色的部分是排序好的序列。对于长度为n的序列,整个过程需进行n-1趟操作,每一趟将未排序的序列从右至左比较相邻两元素,如果逆序则交换位置,如图中第一趟开始到第二趟开始的过程。每进行一趟操作之后,未排序序列中的最小元素会冒泡至序列头部,sorted序列元素个数加1,unsorted序列元素个数减1,直至unsorted序列中只有一个元素时终止,这个元素为最大元素,不需进行其他操作就能得到整个序列的升序序列。

二.代码实现

      下面是冒泡排序的C++实现:

#include<iostream>
#include<vector>
using namespace std;
/** * @brief 对向量v进行冒泡排序 * @param v 待排序的向量 */ void BubbleSort(vector<int> &v) { for(int i = 0; i < v.size() - 1; i++) for(int j = v.size() - 1; j > i; j--) if(v[j-1] > v[j]) swap(v[j-1], v[j]); } int main() { //arr为要排序的数组 int arr[] = {5,2,4,7,10,9,8,1,6,3}; //把数组放入向量中 vector<int> v(arr, arr + sizeof(arr)/sizeof(int)); //对向量使用插入排序 BubbleSort(v); //按顺序打印排序后向量中的所有元素 copy (v.begin(), v.end(), ostream_iterator<int> (cout, " ")); cout << endl; }

 

 

三.算法分析

(1)时间复杂度

   无论待排序的序列怎样,都要进行n-1趟遍历,共要进行n(n-1)/2次比较操作;当序列已排序时不需要进行交换操作,逆序时需要进行n(n-1)/2次交换操作。所以算法的时间复杂度为o(n2)

(2)稳定性

   稳定性是指对于原有序列中的等值元素,是否在排序后不改变它们的相对顺序关系。分析易知冒泡排序是稳定的。

(3)适合范围

       数据量比较小时可以使用。

(4)算法改进

   在内层循环设置一个flag记录是否在内层循环的某一趟过程中进行了交换操作,如果没有则说明已排好序,可以终止循环,减少后面不必要的比较。

      

      

posted @ 2019-05-11 22:42  バニー  阅读(326)  评论(0编辑  收藏  举报