赞
踩
所谓交换,意思是说根据所给的序列,对其中的两个元素进行大小比较,若为逆序,那么我们就交换它。这样就达到了排序的目的。接下来介绍最简单的交换排序——冒泡排序。
冒泡排序的原理很简单,它反复遍历要排序的列表,比较每对相邻的项目,如果它们的顺序错误则交换它们。 重复遍历列表,直到不需要交换,这表示列表已排序。我们可以从后往前(或者从前往后)两两比较相邻的元素,若为逆序,则交换他们。(这跟插入排序不同,插入排序一开始是局部排序,也就是说一开始排完的数字的位置,有可能下次排序的时候还会变动,而冒泡排序是全局排序,一旦位置排好就是固定位置)。
举个例子来说说冒泡排序的步骤:
假设我们对 5 1 4 2 8 这一组数据进行排序,那么第一趟的过程如下:
如果这个时候我们将图倒过来看,就会发现5就像从底下往上冒的水泡,这也是为什么这个算法称为冒泡排序的原因。
好,接下来我们看看第二趟会发生什么:
那么我们对5排完之后,应该对谁排序呢?当然是对 1 了,因为我们是遍历要排序的序列的,得按顺序来。于是发现1比后面的都小,于是不用交换,保留原地不动。(这个时候就注意了,1是不动没错,那么就意味着它真的不动?当然不是,它还是得跟其他元素遍历比较,否则我怎么知道它比其他的元素都要小?所以这是一种对时间资源的浪费)。
排完之后,对4排序,重复第一步的算法,如图所示;
排完之后,对2排序,(实际上这个时候,我们的排序已经完成,但是对于算法来说它并不知道此时的序列已经处于有序状态,因此它依旧执行比较操作,依旧执行遍历,直到所有要排序的元素都已经处于有序状态)
下面贴一个动态图(来自维基百科),直观的描述这一过程:
下面我们用C++语言来写一下这个算法
#include <iostream> #include <vector> using namespace std; /*函数声明*/ void bubbleSort(vector<int> &vec); void swap(int &i, int &j); /*主函数*/ int main() { vector<int> vec; cout << "请输入待排序的序列" << endl; //假设我们对5个数进行排序 for (int i = 0; i < 5; i++) { int n; cin >> n; vec.push_back(n); } bubbleSort(vec);//使用希尔排序对vector进行排序 //输出结果 cout << "冒泡排序后:" << endl; for (int k = 0; k < vec.size(); k++) { cout << vec[k] << " "; } return 0; } //冒泡排序的实现,由小到大 void bubbleSort(vector<int> &vec) { //遍历序列中的每个元素 for (int i = 0; i < vec.size() - 1; i++) { bool IsSwap = false; //设立是否交换的标记 for (int j = vec.size() - 1; j > i; j--) { //一趟排序 if (vec[j - 1] > vec[j]) { //后面的大于左边的大于右边的数,交换 swap(vec[j - 1], vec[j]); IsSwap = true;//交换标记为true } } //当交换标记为flase的时候,意味着本次遍历没有发生交换,跳出循环 if (IsSwap = false) return; } } //交换两个数的函数 void swap(int &i, int &j) { int temp = j; j = i; i = temp; }
显然这种做法造成了极大的时间浪费,做了很多不必要的操作。考虑极端的情况,当被排数列有序的时候,要进行n - 1次比较。(最后一次不用比较,因为已经排好)。当为逆序的时候,进行N-1次排序,并且,第I趟要进行N-I次比较,复杂度为O(n^2).
另外一种用的最广泛的交换排序,叫快速排序,我之前写过我就不再赘述了,链接贴上:C++抽象编程——算法分析(6)——快速排序算法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。