mooc_排序

来源:互联网 发布:分辨率300的软件 编辑:程序博客网 时间:2024/06/06 20:37

1. 选择排序

时间复杂度 O(n^2)主要过程:    选择排序就是挨着选,选到小的放前面    想选小的,就要有比较的对象,    每次默认被选择数组的第一个数是最小值,然后依次和后面的数进行比较,获取剩余数组中最小值的下标,    然后与被选择数组的第一个数交换,完成一次选择
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 = 10000selectSort:0.117953snumber = 100000         selectSort:11.019439s                               
从上面的运行结果来看,计算量增加10倍,时间增加了100倍, 符合O(N^2)的时间复杂度

2. 插入排序

时间复杂度 O(n^2)主要过程:       一点一点的排序,就是        先排前两个数,使其有序        再排前三个数,使其有序        再排前四个数,使其有序        ...        ...        再排最后.. 就全都有序了        在实现的时候注意的点是,可以直接从下标1开始循环,因为只有一个数的话,本身就是有序的,        再就是,以从小到大排来说,如果监测到前面的数已经比当前的数小了,            那就可以跳出当前循环了,毕竟前面的原本就是有序的
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  
上面的排序有优化的空间,因为一次交换等于三次赋值,所以尽量不用交换而是记录下每次新加入的数需要放到的位置,然后后面的数全部向后移动一位最后把新加入的数放到记录下的位置
 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  
插入排序在处理近乎有序的数列中,速度趋向于O(N), 因为他只要判断前面是有序的,就进行下一次的比较所以在处理那些近乎有序的数列时,可以优先考虑

3. 冒泡排序

时间复杂度为O(n^2)主要过程:    第一个数和第二个数比较,大的话就交换,第二个数在和第三个数进行比较,大的话交换,这样依次交换过去,最大的数最终会放在数组的最后.    然后再进行第一个跟第二个数比较,大的话就交换,第二个数在和第三个数进行比较,大的话交换,知道把倒数第二大的数放到倒数第二个,    。。。    。。。    最后全部比完之后,从后到前,从大到小,也就有序了
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 = 10000selectSort:0.117713sinsertSort:0.072229sbubbleSort:0.306428s                                

4. 希尔排序

时间复杂度:O(N*logN)    希尔排序是比较特殊的排序,是插入排序的改良的排序算法,他的步长是经过调整的,主要过程:    比如数组为 6 5   3   1   8   7   2   4     初始步长为3的情况下6 5 3作为前三个数是不需要调整的,从1开始,1向前跳三位,来到6的这个位置,进行比较,1比6小,    所以1跟6的位置进行交换,这样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,所以2和6交换,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)的这样的级别
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;    }}

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

#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
#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;}
0 0
原创粉丝点击