排序 - 选择/插入/冒泡/希尔

from : https://blog.csdn.net/a312024054/article/details/69678785

1. 选择排序

时间复杂度 O(n^2)

主要过程:
    选择排序就是挨着选,选到小的放前面
    想选小的,就要有比较的对象,
    每次默认被选择数组的第一个数是最小值,然后依次和后面的数进行比较,获取剩余数组中最小值的下标,
    然后与被选择数组的第一个数交换,完成一次选择

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
template <typename T>                    
void selectSort(T arr[], int n) {        
    for(int i =0 ; i < n; i++) {         
        int minIndex = i;                
        for (int j = i+1; j < n; j++) {  
            if(arr[minIndex] > arr[j])   
                minIndex = j;            
        }                                
        swap(arr[i], arr[minIndex]);     
    }                                    
}            


number = 10000
selectSort:0.117953s

number = 100000         
selectSort:11.019439s                               
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
从上面的运行结果来看,计算量增加10倍,时间增加了100倍, 符合O(N^2)的时间复杂度

    
    
  • 1
  • 2

2. 插入排序

时间复杂度 O(n^2)

主要过程:   
    一点一点的排序,就是
        先排前两个数,使其有序
        再排前三个数,使其有序
        再排前四个数,使其有序
        ...
        ...
        再排最后.. 就全都有序了
        在实现的时候注意的点是,可以直接从下标1开始循环,因为只有一个数的话,本身就是有序的,
        再就是,以从小到大排来说,如果监测到前面的数已经比当前的数小了,
            那就可以跳出当前循环了,毕竟前面的原本就是有序的

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
template <typename T>
void insertSort(T arr[], int n) {         
    for(int i = 1; i < n; i++) {
        // i ~ 0 就是需要进行排序的前几个
        for( int j = i; j > 0; j--) {
            if( arr[j] < arr[j-1] ) {
                swap(arr[j], arr[j-1]);
            } else {
                break;
            }
        }
    }
}

///////////////////
number = 10000        
selectSort:0.127038s  
insertSort:0.145065s  
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
上面的排序有优化的空间,因为一次交换等于三次赋值,所以尽量不用交换
而是记录下每次新加入的数需要放到的位置,然后后面的数全部向后移动一位
最后把新加入的数放到记录下的位置

    
    
  • 1
  • 2
  • 3
  • 4
 template <typename T>
 void insertSort(T arr[], int n) {  
     for(int i = 1; i < n; i++) {

         T e = arr[i];              
         int j;                     
         for(j = i; j > 0; j--) {   
             if( arr[j-1] > e ) {   
                 arr[j] = arr[j-1]; 
             } else {               
                 break;             
             }                      
         }                          
         arr[j] = e;                
     }                              
 }                   

//并且为了美观,可以把if的条件提到for中
 template <typename T>
 void insertSort(T arr[], int n) {  
     for(int i = 1; i < n; i++) {

         T e = arr[i];              
         int j;                     
         for(j = i; j > 0 && arr[j-1] > e ; j--) {   
             arr[j] = arr[j-1];             
         }                          
         arr[j] = e;                
     }                              
 }                  

///////////////////
number = 10000       
selectSort:0.116369s 
insertSort:0.076550s  

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
插入排序在处理近乎有序的数列中,速度趋向于O(N), 因为他只要判断前面是有序的,就进行下一次的比较
所以在处理那些近乎有序的数列时,可以优先考虑

    
    
  • 1
  • 2
  • 3

3. 冒泡排序

时间复杂度为O(n^2)

主要过程:
    第一个数和第二个数比较,大的话就交换,第二个数在和第三个数进行比较,大的话交换,这样依次交换过去,最大的数最终会放在数组的最后.
    然后再进行第一个跟第二个数比较,大的话就交换,第二个数在和第三个数进行比较,大的话交换,知道把倒数第二大的数放到倒数第二个,
    。。。
    。。。
    最后全部比完之后,从后到前,从大到小,也就有序了

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
template <typename T>                      
void bubbleSort(T arr[], int n) {          
 for(int i = 0; i < n; i++) {           
     for(int j = 1; j < n-i; j++ ) {    
         if(arr[j] < arr[j-1])          
         {                              
             swap(arr[j], arr[j-1]);    
         }                              
     }                                  
  }                                      
}          

///////
number = 10000
selectSort:0.117713s
insertSort:0.072229s
bubbleSort:0.306428s                                
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

4. 希尔排序

时间复杂度:O(N*logN)

    希尔排序是比较特殊的排序,是插入排序的改良的排序算法,他的步长是经过调整的,
主要过程:
    比如数组为 6 5   3   1   8   7   2   4 
    初始步长为3的情况下6 5 3作为前三个数是不需要调整的,从1开始,1向前跳三位,来到6的这个位置,进行比较,16小,
    所以16的位置进行交换,这样1就到了位置0, 再往前三位就越界了,所以交换的过程停止
            数组   1  5   3   6   8   7   2   4
    下面在处理8这个数,8向前跳三位是和5进行比较的,发现跟5比较,8>5,直接停止交换过程,进行下一个数的比较
    就来到了7这个数的位置,7再向前跳三位,发现7>3的,再次停止
    到了2这个位置,2向前跳三位,跟6比较,2<6,所以26交换,2再向前跳三位,此时发现,2应该和1进行比较,2>1,所以2停在原位置,
            数组   1  5   3   2   8   7   6   4
    接下来处理4这个数,4向前跳三位,来到了8这个数的位置,4<8,交换,4再向前跳三位比较,发现4<5,进行交换,4来到了位置1,不能在向前跳了,
        这样这个步长为3的插入排序就结束了
        步长为3之后,还有步长为2,最后来到步长为1,也就是一个经典的插入排序
        希尔排序最终都会以步长为1的排序结束

    希尔排序的关键就在于步长的选择,步长选择越优,时间复杂度越低,步长选择越劣,就越趋近于时间复杂度O(n^2)的这样的级别

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
template<typename T>
void shellSort(T arr[], int n)
{
    int h = 1;
    while( h < n/3 )
        h = 3 * h + 1;
    // 计算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...

    while( h >= 1 ){

        // h-sort the array
        for( int i = h ; i < n ; i ++ ){

            // 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
            T e = arr[i];
            int j;
            for( j = i ; j >= h && e < arr[j-h] ; j -= h )
                arr[j] = arr[j-h];
            arr[j] = e;
        }
        h /= 3;
    }
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

——————————–完整代码———————————–

#ifndef SORTTESTHELPER_H
#define SORTTESTHELPER_H

#include <iostream>
#include <ctime>
#include <cassert>
#include<iomanip>

using namespace std;

namespace SortTextHelper {
    // 生成有n个元素的随机数组,元素的范围[rangeL, rangeR]
    int *generateRangeArray(int n, int rangeL, int rangeR) {

        assert(rangeL <= rangeR);

        int * arr = new int[n];

        srand(time(NULL));
        for(int i=0; i < n; i++){
            arr[i] = rand() % (rangeR-rangeL+1) + rangeL;
        }
        return arr;
    }

    template <typename T>
        void printArray(T arr[], int n) {
            for(int i =0 ; i < n; i++) {
                cout << arr[i] << " ";
            }
            cout << endl;
        }

    template <typename T>
        bool isSorted(T arr[], int n) {
            for(int i = 0; i < n-1; i++) {
                if( arr[i+1] < arr[i] ) {
                    return false;
                }
            }
            return true;
        }

    template <typename T>
        void testSort(const char *sortName,void (*sort)(T arr[], int ), T arr[], int n) {

            clock_t startTime = clock();
            sort(arr, n);
            clock_t endTime = clock();

            assert(isSorted(arr,n));

            cout << sortName << ":" << setiosflags(ios::fixed) << double(endTime-startTime)  / CLOCKS_PER_SEC << "s" << endl;
        }

        int * copyIntArray(int a[], int n) {
            int *arr = new int[n];
            copy(a, a+n, arr);
            return arr;
        }
}

#endif //SORTTESTHELPER_H

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
#include <iostream>
#include "SortTextHelper.h"

using namespace std;

template <typename T>
void selectSort(T arr[], int n) {
    for(int i =0 ; i < n; i++) {
        int minIndex = i;
        for (int j = i+1; j < n; j++) {
            if(arr[minIndex] > arr[j])
                minIndex = j;
        }
        swap(arr[i], arr[minIndex]);
    }
}

template <typename T>
void insertSort(T arr[], int n) {
    for(int i = 1; i < n; i++) {

        T e = arr[i];
        int j;
        for(j = i; j > 0 && arr[j-1] > e; j--) {
            arr[j] = arr[j-1];
        }
        arr[j] = e;
    }
}

template <typename T>
void bubbleSort(T arr[], int n) {
    for(int i = 0; i < n; i++) {
        bool bSwapped = false;
        for(int j = 1; j < n-i; j++ ) {
            if(arr[j] < arr[j-1])
            {
                swap(arr[j], arr[j-1]);
                bSwapped = true;
            }
        }
        if(bSwapped == false) {
            break;
        }
    }
}

template<typename T>
void shellSort(T arr[], int n){

    int h = 1;
    while( h < n/3  )
        h = 3 * h + 1;
    // 计算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...

    while( h >= 1  ){

        // h-sort the array
        for( int i = h ; i < n ; i ++  ){

        // 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
            T e = arr[i];
            int j;
            for( j = i ; j >= h && e < arr[j-h] ; j -= h  )
                arr[j] = arr[j-h];
            arr[j] = e;
        }
        h /= 3;
    }
}
int main(int argc, char *argv[])
{

    int n = 10000;
    cout << "number = " << n << endl;
    int *arr = SortTextHelper::generateRangeArray(n, 0, n);
    int *arr2 = SortTextHelper::copyIntArray(arr, n);
    int *arr3 = SortTextHelper::copyIntArray(arr, n);
    int *arr4 = SortTextHelper::copyIntArray(arr, n);

    SortTextHelper::testSort("selectSort", selectSort, arr, n);
    SortTextHelper::testSort("insertSort", insertSort, arr2, n);
    SortTextHelper::testSort("bubbleSort", bubbleSort, arr3, n);
    SortTextHelper::testSort("shellSort ", shellSort, arr4, n);

    //SortTextHelper::printArray(arr, n);

    delete[] arr;
    delete[] arr2;
    delete[] arr3;
    delete[] arr4;
    return 0;
}

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

1. 选择排序

时间复杂度 O(n^2)

主要过程:
    选择排序就是挨着选,选到小的放前面
    想选小的,就要有比较的对象,
    每次默认被选择数组的第一个数是最小值,然后依次和后面的数进行比较,获取剩余数组中最小值的下标,
    然后与被选择数组的第一个数交换,完成一次选择

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
template <typename T>                    
void selectSort(T arr[], int n) {        
    for(int i =0 ; i < n; i++) {         
        int minIndex = i;                
        for (int j = i+1; j < n; j++) {  
            if(arr[minIndex] > arr[j])   
                minIndex = j;            
        }                                
        swap(arr[i], arr[minIndex]);     
    }                                    
}            


number = 10000
selectSort:0.117953s

number = 100000         
selectSort:11.019439s                               
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
从上面的运行结果来看,计算量增加10倍,时间增加了100倍, 符合O(N^2)的时间复杂度

  
  
  • 1
  • 2

2. 插入排序

时间复杂度 O(n^2)

主要过程:   
    一点一点的排序,就是
        先排前两个数,使其有序
        再排前三个数,使其有序
        再排前四个数,使其有序
        ...
        ...
        再排最后.. 就全都有序了
        在实现的时候注意的点是,可以直接从下标1开始循环,因为只有一个数的话,本身就是有序的,
        再就是,以从小到大排来说,如果监测到前面的数已经比当前的数小了,
            那就可以跳出当前循环了,毕竟前面的原本就是有序的

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
template <typename T>
void insertSort(T arr[], int n) {         
    for(int i = 1; i < n; i++) {
        // i ~ 0 就是需要进行排序的前几个
        for( int j = i; j > 0; j--) {
            if( arr[j] < arr[j-1] ) {
                swap(arr[j], arr[j-1]);
            } else {
                break;
            }
        }
    }
}

///////////////////
number = 10000        
selectSort:0.127038s  
insertSort:0.145065s  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
上面的排序有优化的空间,因为一次交换等于三次赋值,所以尽量不用交换
而是记录下每次新加入的数需要放到的位置,然后后面的数全部向后移动一位
最后把新加入的数放到记录下的位置

  
  
  • 1
  • 2
  • 3
  • 4
 template <typename T>
 void insertSort(T arr[], int n) {  
     for(int i = 1; i < n; i++) {

         T e = arr[i];              
         int j;                     
         for(j = i; j > 0; j--) {   
             if( arr[j-1] > e ) {   
                 arr[j] = arr[j-1]; 
             } else {               
                 break;             
             }                      
         }                          
         arr[j] = e;                
     }                              
 }                   

//并且为了美观,可以把if的条件提到for中
 template <typename T>
 void insertSort(T arr[], int n) {  
     for(int i = 1; i < n; i++) {

         T e = arr[i];              
         int j;                     
         for(j = i; j > 0 && arr[j-1] > e ; j--) {   
             arr[j] = arr[j-1];             
         }                          
         arr[j] = e;                
     }                              
 }                  

///////////////////
number = 10000       
selectSort:0.116369s 
insertSort:0.076550s  

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
插入排序在处理近乎有序的数列中,速度趋向于O(N), 因为他只要判断前面是有序的,就进行下一次的比较
所以在处理那些近乎有序的数列时,可以优先考虑

  
  
  • 1
  • 2
  • 3

3. 冒泡排序

时间复杂度为O(n^2)

主要过程:
    第一个数和第二个数比较,大的话就交换,第二个数在和第三个数进行比较,大的话交换,这样依次交换过去,最大的数最终会放在数组的最后.
    然后再进行第一个跟第二个数比较,大的话就交换,第二个数在和第三个数进行比较,大的话交换,知道把倒数第二大的数放到倒数第二个,
    。。。
    。。。
    最后全部比完之后,从后到前,从大到小,也就有序了

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
template <typename T>                      
void bubbleSort(T arr[], int n) {          
 for(int i = 0; i < n; i++) {           
     for(int j = 1; j < n-i; j++ ) {    
         if(arr[j] < arr[j-1])          
         {                              
             swap(arr[j], arr[j-1]);    
         }                              
     }                                  
  }                                      
}          

///////
number = 10000
selectSort:0.117713s
insertSort:0.072229s
bubbleSort:0.306428s                                
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

4. 希尔排序

时间复杂度:O(N*logN)

    希尔排序是比较特殊的排序,是插入排序的改良的排序算法,他的步长是经过调整的,
主要过程:
    比如数组为 6 5   3   1   8   7   2   4 
    初始步长为3的情况下6 5 3作为前三个数是不需要调整的,从1开始,1向前跳三位,来到6的这个位置,进行比较,16小,
    所以16的位置进行交换,这样1就到了位置0, 再往前三位就越界了,所以交换的过程停止
            数组   1  5   3   6   8   7   2   4
    下面在处理8这个数,8向前跳三位是和5进行比较的,发现跟5比较,8>5,直接停止交换过程,进行下一个数的比较
    就来到了7这个数的位置,7再向前跳三位,发现7>3的,再次停止
    到了2这个位置,2向前跳三位,跟6比较,2<6,所以26交换,2再向前跳三位,此时发现,2应该和1进行比较,2>1,所以2停在原位置,
            数组   1  5   3   2   8   7   6   4
    接下来处理4这个数,4向前跳三位,来到了8这个数的位置,4<8,交换,4再向前跳三位比较,发现4<5,进行交换,4来到了位置1,不能在向前跳了,
        这样这个步长为3的插入排序就结束了
        步长为3之后,还有步长为2,最后来到步长为1,也就是一个经典的插入排序
        希尔排序最终都会以步长为1的排序结束

    希尔排序的关键就在于步长的选择,步长选择越优,时间复杂度越低,步长选择越劣,就越趋近于时间复杂度O(n^2)的这样的级别

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
template<typename T>
void shellSort(T arr[], int n)
{
    int h = 1;
    while( h < n/3 )
        h = 3 * h + 1;
    // 计算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...

    while( h >= 1 ){

        // h-sort the array
        for( int i = h ; i < n ; i ++ ){

            // 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
            T e = arr[i];
            int j;
            for( j = i ; j >= h && e < arr[j-h] ; j -= h )
                arr[j] = arr[j-h];
            arr[j] = e;
        }
        h /= 3;
    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

——————————–完整代码———————————–

#ifndef SORTTESTHELPER_H
#define SORTTESTHELPER_H

#include <iostream>
#include <ctime>
#include <cassert>
#include<iomanip>

using namespace std;

namespace SortTextHelper {
    // 生成有n个元素的随机数组,元素的范围[rangeL, rangeR]
    int *generateRangeArray(int n, int rangeL, int rangeR) {

        assert(rangeL <= rangeR);

        int * arr = new int[n];

        srand(time(NULL));
        for(int i=0; i < n; i++){
            arr[i] = rand() % (rangeR-rangeL+1) + rangeL;
        }
        return arr;
    }

    template <typename T>
        void printArray(T arr[], int n) {
            for(int i =0 ; i < n; i++) {
                cout << arr[i] << " ";
            }
            cout << endl;
        }

    template <typename T>
        bool isSorted(T arr[], int n) {
            for(int i = 0; i < n-1; i++) {
                if( arr[i+1] < arr[i] ) {
                    return false;
                }
            }
            return true;
        }

    template <typename T>
        void testSort(const char *sortName,void (*sort)(T arr[], int ), T arr[], int n) {

            clock_t startTime = clock();
            sort(arr, n);
            clock_t endTime = clock();

            assert(isSorted(arr,n));

            cout << sortName << ":" << setiosflags(ios::fixed) << double(endTime-startTime)  / CLOCKS_PER_SEC << "s" << endl;
        }

        int * copyIntArray(int a[], int n) {
            int *arr = new int[n];
            copy(a, a+n, arr);
            return arr;
        }
}

#endif //SORTTESTHELPER_H

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
#include <iostream>
#include "SortTextHelper.h"

using namespace std;

template <typename T>
void selectSort(T arr[], int n) {
    for(int i =0 ; i < n; i++) {
        int minIndex = i;
        for (int j = i+1; j < n; j++) {
            if(arr[minIndex] > arr[j])
                minIndex = j;
        }
        swap(arr[i], arr[minIndex]);
    }
}

template <typename T>
void insertSort(T arr[], int n) {
    for(int i = 1; i < n; i++) {

        T e = arr[i];
        int j;
        for(j = i; j > 0 && arr[j-1] > e; j--) {
            arr[j] = arr[j-1];
        }
        arr[j] = e;
    }
}

template <typename T>
void bubbleSort(T arr[], int n) {
    for(int i = 0; i < n; i++) {
        bool bSwapped = false;
        for(int j = 1; j < n-i; j++ ) {
            if(arr[j] < arr[j-1])
            {
                swap(arr[j], arr[j-1]);
                bSwapped = true;
            }
        }
        if(bSwapped == false) {
            break;
        }
    }
}

template<typename T>
void shellSort(T arr[], int n){

    int h = 1;
    while( h < n/3  )
        h = 3 * h + 1;
    // 计算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...

    while( h >= 1  ){

        // h-sort the array
        for( int i = h ; i < n ; i ++  ){

        // 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
            T e = arr[i];
            int j;
            for( j = i ; j >= h && e < arr[j-h] ; j -= h  )
                arr[j] = arr[j-h];
            arr[j] = e;
        }
        h /= 3;
    }
}
int main(int argc, char *argv[])
{

    int n = 10000;
    cout << "number = " << n << endl;
    int *arr = SortTextHelper::generateRangeArray(n, 0, n);
    int *arr2 = SortTextHelper::copyIntArray(arr, n);
    int *arr3 = SortTextHelper::copyIntArray(arr, n);
    int *arr4 = SortTextHelper::copyIntArray(arr, n);

    SortTextHelper::testSort("selectSort", selectSort, arr, n);
    SortTextHelper::testSort("insertSort", insertSort, arr2, n);
    SortTextHelper::testSort("bubbleSort", bubbleSort, arr3, n);
    SortTextHelper::testSort("shellSort ", shellSort, arr4, n);

    //SortTextHelper::printArray(arr, n);

    delete[] arr;
    delete[] arr2;
    delete[] arr3;
    delete[] arr4;
    return 0;
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

猜你喜欢

转载自blog.csdn.net/hawkcici160/article/details/81322040