冒泡排序也属于简单的排序方法,时间复杂度为:O(n^2)。
(1) 冒泡排序的思想
冒泡排序的思想就是:该排序算法意在从后往前像气泡一样,依次冒出数组中值小的元素;或者从前往后依次冒出数组中值大的元素。
以升序为例,假设数组的长度为size。从数组的最后一个元素(即第size-1个元素)开始,从后往前两两进行比较,即最开始比较第size-1个元素和第size-2个元素的值的大小,若发现前者比后者小,则进行交换,否则不交换,之后不管是否已进行交换操作,继续往前遍历,遍历到第0个元素为止,这时候确定第0个元素为数组中最小的值;然后,再重新开始比较第size-1个元素和第size-2个元素的值的大小,对其进行前面所述的操作,直到遍历到第1个元素为止,这时候确定第1个元素为数组中第二小的值;以此类推,直到对整个数组操作完为止。
为了更好地理解该算法的思想,我们来看以下图片:
从上图可以知道,原始数组为:5 2 3 8 1,以排升序为例,接下来进行分步操作。
第一步:从数组的最后一个元素(即第4个元素)开始,比较第4个元素1和第3个元素8的大小,发现8比1大,故进行交换,此时数组变为:5 2 3 1 8;往前比较第3个元素1和第2个元素3的大小,发现3比1大,故进行交换,此时数组变为:5 2 1 3 8;再往前比较第2个元素1和第1个元素2的大小,发现2比1大,故进行交换,此时数组变为:5 1 2 3 8;再往前比较第1个元素1和第0个元素5的大小,发现5比1大,故进行交换,此时数组变为:1 5 2 3 8;由于遍历到了第0个元素,故确定了第0个元素1为数组中最小的值,且该步骤完毕;
第二步:从数组的第4个元素开始,比较第4个元素8和第3个元素3的大小,发现3比8小,故不进行交换,此时数组无变化;往前比较第3个元素3和第2个元素2的大小,发现2比3小,故不进行交换,此时数组无变化;再往前比较第2个元素2个第1个元素5的大小,发现5比2大,故进行交换,此时数组变为:1 2 5 3 8;由于遍历到了第1个元素,故确定第1个元素2为除第0个元素外值最小的元素,且该步骤完毕;
第三步:从数组的第4个元素开始,比较第4个元素8和第3个元素3的大小,发现3比8小,故不进行交换,此时数组仍为:1 2 5 3 8;往前比较第3个元素3和第2个元素5的大小,发现5比3大,故进行交换,此时数组变为:1 2 3 5 8;由于遍历到了第2个元素,故确定第2个元素3为该位置到数组最后中最小的元素,且该步骤完毕;
第四步:从数组的第4个元素开始,比较比较第4个元素8和第3个元素5的大小,发现5比8小,故不进行交换,此时数组仍为:1 2 3 5 8;由于遍历到了第3个元素,故确定第3个元素5为该位置到数组最后中最小的元素,却该步骤完毕;
最后,由于确定了除最后的元素外的其他的元素所应该在的位置,故最后的元素必为数组中最大的元素,且整个排序结束。
(2) 冒泡排序的实现
本次排序算法采用C++模版编程来实现。
#include <iostream>
#include <iterator>
using namespace std;
template<class T,size_t N>
void PrintArr(T (&arr)[N]) {
copy(arr,arr+N,ostream_iterator<T>(cout," "));
cout << endl;
}
template<class T,size_t N>
void BubbleSort(T (&arr)[N]) {
for (int i=0; i<N; i++) {
for (int j=N-1; j>i; j--) {
PrintArr(arr);
if(arr[j]<arr[j-1])
swap(arr[j], arr[j-1]);
}
}
}
template<class SortFunc>
void Test(SortFunc sort) {
int arr[]= {5,2,3,8,1};
sort(arr);
cout << "final:" << endl;
PrintArr(arr);
}
int main(){
cout << "BubbleSort:"<<endl;
Test(BubbleSort<int,5>);
}
原始数组为:5 2 3 8 1
程序运行结果为:1 2 3 5 8