冒泡排序的实现和优化及其与插入,选择排序的比较

备注:这里使用的插入排序和选择排序都是经过优化后的详细优化请查看上一条博客,编译器使用DEV-C++

冒泡排序算法的运作如下:(从后往前)

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

3.针对所有的元素重复以上的步骤,除了最后一个。

4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

 


测试代码:

 1 #ifndef OPTIONAL_01_BUBBLE_SORT_SORTTESTHELPER_H
 2 #define OPTIONAL_01_BUBBLE_SORT_SORTTESTHELPER_H
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <ctime>
 6 #include <string>
 7 #include <cassert>
 8 using namespace std;
 9 namespace SortTestHelper {
10     // 生成有n个元素的随机数组,每个元素的随机范围为[rangeL, rangeR]
11     int *generateRandomArray(int n, int range_l, int range_r) {
12         int *arr = new int[n];
13         srand(time(NULL));
14         for (int i = 0; i < n; i++)
15             arr[i] = rand() % (range_r - range_l + 1) + range_l;
16         return arr;
17     }
18     // 生成一个近乎有序的数组
19     // 首先生成一个含有[0...n-1]的完全有序数组, 之后随机交换swapTimes对数据
20     // swapTimes定义了数组的无序程度
21     int *generateNearlyOrderedArray(int n, int swapTimes){
22         int *arr = new int[n];
23         for(int i = 0 ; i < n ; i ++ )
24             arr[i] = i;
25         srand(time(NULL));
26         for( int i = 0 ; i < swapTimes ; i ++ ){
27             int posx = rand()%n;
28             int posy = rand()%n;
29             swap( arr[posx] , arr[posy] );
30         }
31         return arr;
32     }
33     // 拷贝整型数组a中的所有元素到一个新的数组, 并返回新的数组
34     int *copyIntArray(int a[], int n){
35         int *arr = new int[n];
36         copy(a, a+n, arr);
37         return arr;
38     }
39     // 打印arr数组的所有内容
40     template<typename T>
41     void printArray(T arr[], int n) {
42         for (int i = 0; i < n; i++)
43             cout << arr[i] << " ";
44         cout << endl;
45         return;
46     }
47     // 判断arr数组是否有序
48     template<typename T>
49     bool isSorted(T arr[], int n) {
50         for (int i = 0; i < n - 1; i++)
51             if (arr[i] > arr[i + 1])
52                 return false;
53         return true;
54     }
55     // 测试sort排序算法排序arr数组所得到结果的正确性和算法运行时间
56     template<typename T>
57     void testSort(const string &sortName, void (*sort)(T[], int), T arr[], int n) {
58         clock_t startTime = clock();
59         sort(arr, n);
60         clock_t endTime = clock();
61         cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " s"<<endl;
62         assert(isSorted(arr, n));
63         return;
64     }
65 };
66 #endif

选择排序代码:

 1 #ifndef OPTIONAL_01_BUBBLE_SORT_SELECTIONSORT_H
 2 #define OPTIONAL_01_BUBBLE_SORT_SELECTIONSORT_H
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 template<typename T>
 7 void selectionSort(T arr[], int n){
 8     for(int i = 0 ; i < n ; i ++){
 9         int minIndex = i;
10         for( int j = i + 1 ; j < n ; j ++ )
11             if( arr[j] < arr[minIndex] )
12                 minIndex = j;
13         swap( arr[i] , arr[minIndex] );
14     }
15 }
16 #endif

插入排序代码:

 1 #ifndef OPTIONAL_01_BUBBLE_SORT_INSERTIONSORT_H
 2 #define OPTIONAL_01_BUBBLE_SORT_INSERTIONSORT_H
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 template<typename T>
 7 void insertionSort(T arr[], int n){
 8     for( int i = 1 ; i < n ; i ++ ) {
 9         T e = arr[i];
10         int j;
11         for (j = i; j > 0 && arr[j-1] > e; j--)
12             arr[j] = arr[j-1];
13         arr[j] = e;
14     }
15     return;
16 }
17 #endif 

冒泡排序以及优化代码:

  1 #include <iostream>
  2 #include <algorithm>
  3 #include "SortTestHelper.h"
  4 #include "SelectionSort.h"
  5 #include "InsertionSort.h"
  6 using namespace std;
  7 // 第一版bubbleSort
  8 template<typename T>
  9 void bubbleSort( T arr[] , int n){
 10     bool swapped;
 11     do{
 12         swapped = false;
 13         for( int i = 1 ; i < n ; i ++ )
 14             if( arr[i-1] > arr[i] ){
 15                 swap( arr[i-1] , arr[i] );
 16                 swapped = true;
 17             }
 18         // 优化, 每一趟Bubble Sort都将最大的元素放在了最后的位置
 19         // 所以下一次排序, 最后的元素可以不再考虑
 20         n --;
 21     }while(swapped);
 22 }
 23 // 第二版bubbleSort,使用newn进行优化
 24 template<typename T>
 25 void bubbleSort2( T arr[] , int n){
 26     int newn; // 使用newn进行优化
 27     do{
 28         newn = 0;
 29         for( int i = 1 ; i < n ; i ++ )
 30             if( arr[i-1] > arr[i] ){
 31                 swap( arr[i-1] , arr[i] );
 32                 // 记录最后一次的交换位置,在此之后的元素在下一轮扫描中均不考虑
 33                 newn = i;
 34             }
 35         n = newn;
 36     }while(newn > 0);
 37 }
 38 int main() {
 39     int n = 20000;
 40     // 测试1 一般测试
 41     cout<<"Test for random array, size = "<<n<<", randome range [0, "<<n<<"]"<<endl;
 42     int *arr1 = SortTestHelper::generateRandomArray(n,0,n);
 43     int *arr2 = SortTestHelper::copyIntArray(arr1, n);
 44     int *arr3 = SortTestHelper::copyIntArray(arr1, n);
 45     int *arr4 = SortTestHelper::copyIntArray(arr1, n);
 46 
 47     SortTestHelper::testSort("Selection Sort", selectionSort, arr1, n);
 48     SortTestHelper::testSort("Insertion Sort", insertionSort, arr2, n);
 49     SortTestHelper::testSort("Bubble Sort", bubbleSort, arr3, n);
 50     SortTestHelper::testSort("Bubble Sort 2", bubbleSort, arr4, n);
 51 
 52     delete[] arr1;
 53     delete[] arr2;
 54     delete[] arr3;
 55     delete[] arr4;
 56 
 57     cout<<endl;
 58     // 测试2 测试近乎有序的数组
 59     int swapTimes = 100;
 60     cout<<"Test for nNearly ordered array, size = "<<n<<", swap time = "<<swapTimes<<endl;
 61     arr1 = SortTestHelper::generateNearlyOrderedArray(n, swapTimes);
 62     arr2 = SortTestHelper::copyIntArray(arr1, n);
 63     arr3 = SortTestHelper::copyIntArray(arr1, n);
 64     arr4 = SortTestHelper::copyIntArray(arr1, n);
 65 
 66     SortTestHelper::testSort("Selection Sort", selectionSort, arr1, n);
 67     SortTestHelper::testSort("Insertion Sort", insertionSort, arr2, n);
 68     SortTestHelper::testSort("Bubble Sort", bubbleSort, arr3, n);
 69     SortTestHelper::testSort("Bubble Sort 2", bubbleSort, arr4, n);
 70 
 71     delete[] arr1;
 72     delete[] arr2;
 73     delete[] arr3;
 74     delete[] arr4;
 75 
 76     cout<<endl;
 77     // 测试3 测试完全有序的数组
 78     // 对于完全有序的数组,冒泡排序法也将成为O(n)级别的算法
 79     swapTimes = 0;
 80     n = 10000000;    // 由于插入排序法和冒泡排序法在完全有序的情况下都将成为O(n)算法
 81                      // 所以我们的测试数据规模变大,为1000,0000
 82     cout<<"Test for ordered array, size = " << n << endl;
 83 
 84     arr1 = SortTestHelper::generateNearlyOrderedArray(n, swapTimes);
 85     arr2 = SortTestHelper::copyIntArray(arr1, n);
 86     arr3 = SortTestHelper::copyIntArray(arr1, n);
 87     arr4 = SortTestHelper::copyIntArray(arr1, n);
 88 
 89     // 在这种情况下,不再测试选择排序算法
 90     //SortTestHelper::testSort("Selection Sort", selectionSort, arr1, n);
 91     SortTestHelper::testSort("Insertion Sort", insertionSort, arr2, n);
 92     SortTestHelper::testSort("Bubble Sort", bubbleSort, arr3, n);
 93     SortTestHelper::testSort("Bubble Sort 2", bubbleSort, arr4, n);
 94 
 95     delete[] arr1;
 96     delete[] arr2;
 97     delete[] arr3;
 98     delete[] arr4;
 99     return 0;
100 }

测试结果:

 

转载于:https://www.cnblogs.com/Tom-shushu/p/10067608.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值