常用排序算法代碼整理

Bubble Sort

//
// Created by tim-berners-bai on 17-4-17.
//

#ifndef SORTALGORITHMS_BUBBLESORT_H
#define SORTALGORITHMS_BUBBLESORT_H

#include <iostream>

using namespace std;

template <typename T>
void bubbleSort(T arr[], int n) {
    int m = n;
    for ( int i = 0; i < n - 1; ++i ) {
        for ( int j = 0; j < m - 1; ++j ) {
            if (arr[j] > arr[j + 1])
                swap(arr[j], arr[j + 1]);
        }
        m--;
    }
//    bool swapped;
//    //int newn; // 理論上,可以使用newn進行優化,但實際優化效果較差
//    do{
//        swapped = false;
//        //newn = 0;
//        for( int i = 1 ; i < n ; i ++ )
//            if( arr[i-1] > arr[i] ){
//                swap( arr[i-1] , arr[i] );
//                swapped = true;
//                // 可以記錄最後一次的交換位置,在此之後的元素在下一輪掃描中均不考慮
//                // 實際優化效果較差,因爲引入了newn這個新的變量
//                //newn = n;
//            }
//        //n = newn;
//        // 優化,每一趟Bubble Sort都將最大的元素放在了最後的位置
//        // 所以下一次排序,最後的元素可以不再考慮
//        // 理論上,newn的優化是這個優化的複雜版本,應該更有效
//        // 實測,使用這種簡單優化,時間性能更好
//        n --;
//    }while(swapped);
}


#endif //SORTALGORITHMS_BUBBLESORT_H

Selection Sort

//
// Created by tim-berners-bai on 17-4-16.
//

#ifndef SORTALGORITHMS_SELECTIONSORT_H
#define SORTALGORITHMS_SELECTIONSORT_H

#include <iostream>

using namespace std;

template <typename T>
void selectionSort(T arr[], int n) {
    for (int i = 0; i < n; ++i) {
         // 尋找[i, n)區間裏的最小值
        int minIndex = i;
        for (int j = i + 1; j < n; ++j) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
    swap(arr[i], arr[minIndex]);
    }
}

#endif //SORTALGORITHMS_SELECTIONSORT_H

Insertion Sort

//
// Created by tim-berners-bai on 17-4-16.
//

#ifndef SORTALGORITHMS_INSERTIONSORT_H
#define SORTALGORITHMS_INSERTIONSORT_H

#include <iostream>

using namespace std;

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

    for (int i = 1; i < n; ++i) {

        // 尋找元素 arr[i] 合適的插入位置
        for (int j = i; j > 0 && arr[j - 1] > arr[j]; --j)
            swap(arr[j], arr[j - 1]);
    }
}

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

    for (int i = 1; i < n; ++i) {

        // 尋找元素 arr[i] 合適的插入位置
        T e = arr[i];
        int j;      // j 保存元素 e 應該插入的位置
        for (j = i; j > 0 && e < arr[j - 1]; --j)
            arr[j] = arr[j - 1];
        arr[j] = e;
    }
}

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

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

#endif //SORTALGORITHMS_INSERTIONSORT_H

Shell Sort

//
// Created by tim-berners-bai on 17-4-17.
//

#ifndef SORTALGORITHMS_SHELLSORT_H
#define SORTALGORITHMS_SHELLSORT_H

template<typename T> //可以使用整數或浮點數作爲元素,如果使用類(class)作爲元素則需要重載大於(>)運算符。
void shellSort(T arr[], int len) {
    int gap, i, j;
    T temp;
    for (gap = len >> 1; gap > 0; gap >>= 1)
        for (i = gap; i < len; i++) {
            temp = arr[i];
            for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
                arr[j + gap] = arr[j];
            arr[j + gap] = temp;
        }
}

template <typename T>
void shellSort3(T arr[], int n) {
    int gap;
    for ( gap = n >> 1; gap > 0; gap >>= 1 ) {
        for ( int i = gap; i < n; ++i ) {
           T e = arr[i];
            int j;
            for ( j = i; j >= gap && e < arr[j - gap]; j -= gap ) {
                arr[j] = arr[j - gap];
            }
            arr[j] = e;
        }
    }
}

template<typename T>
void shellSort2(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;
    }
}


#endif //SORTALGORITHMS_SHELLSORT_H

Merge Sort

//
// Created by tim-berners-bai on 17-4-18.
//

#ifndef SORTALGORITHMS_MERGESORT_H
#define SORTALGORITHMS_MERGESORT_H

#include <iostream>
#include "InsertionSort.h"

using namespace std;

// 將arr[l...mid] 和 arr[mid + 1...r] 兩部分進行歸併
template <typename T>
void __merge(T arr[], int l, int mid, int r) {
    T aux[r - l + 1];
    for ( int i = l; i <= r; ++i ) {
        aux[i - l] = arr[i];
    }

    int i = l, j = mid + 1;
    for ( int k = l; k <= r; ++k ) {
        if (i > mid) {
            arr[k] = aux[j - l];
            j++;
        } else if (j > r) {
            arr[k] = aux[i - l];
            i++;
        }
        else if (aux[i - l] < aux[j - l]) {
            arr[k] = aux[i - l];
            i++;
        } else {
            arr[k] = aux[j - l];
            j++;
        } }
}

// 遞歸使用歸併排序,對 arr[l..r]的範圍進行排序
template <typename T>
void __mergeSort(T arr[], int l, int r) {

    if (r - l <= 15) {
        insertionSort(arr, l, r);
        return;
    }

    int mid = l + (r - l) / 2;
    __mergeSort(arr, l, mid);
    __mergeSort(arr, mid + 1, r);
    if (arr[mid] > arr[mid + 1])
        __merge(arr, l, mid, r);
}

template <typename T>
void mergeSort(T arr[], int n) {
    __mergeSort(arr, 0, n - 1);
}

template <typename T>
void mergeSortBU(T arr[], int n) {
//    for (int size = 1; size <= n; size += size) {
//        for (int i = 0; i + size < n; i += size + size) {
//            // 對 arr[i...i+size-1] 和 arr[i+size...i+2*size-1]
//            __merge(arr, i, i + size - 1, min(i + size + size - 1, n - 1));
//        }
//    }
    for (int i = 0; i < n; i += 16) {
            insertionSort(arr, i, min(i + 15, n - 1));
    }
    for (int sz = 16; sz < n; sz += sz) {
        for (int i = 0; i + sz < n; i += sz + sz) {
            if (arr[i + sz - 1] > arr[i + sz])
                __merge(arr, i, i + sz - 1, min(i + sz + sz -1, n - 1));
        }
    }

}

#endif //SORTALGORITHMS_MERGESORT_H

Quick Sort

//
// Created by tim-berners-bai on 17-4-24.
//

#ifndef SORTALGORITHMS_QUICKSORT_H
#define SORTALGORITHMS_QUICKSORT_H

#include <iostream>
#include "InsertionSort.h"

using namespace std;

// 對 arr[l...r]部分進行 partition 操作
// 返回 p, 使得 arr[l...p-1] < arr[p] && arr[p+1...r] > arr[p]
template <typename T>
int __partition(T arr[], int l, int r) {

    swap(arr[rand() % (r - l + 1) + l], arr[l]);
    T v = arr[l];
//      partition_1
//    // arr[l+1...j] < v && arr[j+1...i) > v
//    int j = l;
//    for (int i = l + 1; i <= r; ++i) {
//        if (arr[i] < v) {
//            swap(arr[++j], arr[i]);
//        }
//        if (arr[i] == v) {
//
//        }
//    }
//    swap(arr[l], arr[j]);
//    return j;

    // partition_2
    // arr[l+1...i] <= v && arr[j...r] >= v;
    int i = l + 1, j = r;
    while (true) {
        while (i <= r && arr[i] < v) {
            i ++;
        }
        while (j >= l + 1 && arr[j] > v) {
            j --;
        }
        if (i >= j) {
            break;
        }
        swap(arr[i], arr[j]);
        i++;
        j--;
    }
    swap(arr[l], arr[j]);
    return j;
}

// 對 arr[l...r] 部分進行快速排序
template <typename T>
void __quickSort(T arr[], int l, int r) {
//    if (l >= r)
//        return;
    if  (r - l <= 15) {
        insertionSort(arr, l, r);
        return;
    }

    int p = __partition(arr, l, r);
    __quickSort(arr, l, p - 1);
    __quickSort(arr, p + 1, r);
}

template <typename T>
void quickSort(T arr[], int n) {
    srand(time(NULL));
    __quickSort(arr, 0, n - 1);
}

// 三路快速排序處理 arr[l...r]
// 將 arr[l...r] 分爲 <v; ==v; >v; 三部分
// 之後將遞歸對 <v and >v 兩部分繼續進行三路快速排序
template <typename T>
void __quickSort3Ways(T arr[], int l, int r) {

    if (r - l <= 15) {
        insertionSort(arr, l, r);
        return;
    }
    // partition_3
    swap(arr[l], arr[rand() % (r - l + 1) + l]);
    T v = arr[l];

    int lt = l;         // arr[l+1...lt] < v;
    int gt = r + 1;     // arr[gt...r] > v;
    int i = l + 1;    // arr[lt+1...i) == v;
    while (i < gt) {
        if (arr[i] > v) {
            gt--;
            swap(arr[gt], arr[i]);
        }
        else if (arr[i] < v) {
            lt++;
            swap(arr[lt], arr[i]);
            i++;
        }
        else {
            i++;
        }
    }
    swap(arr[l], arr[lt]);

    __quickSort3Ways(arr, l, lt - 1);
    __quickSort3Ways(arr, gt, r);
}

template <typename T>
void quickSort3Ways(T arr[], int n) {
    srand(time(NULL));
    __quickSort3Ways(arr, 0, n - 1);
}


#endif //SORTALGORITHMS_QUICKSORT_H

Heap Sort

//
// Created by tim-berners-bai on 17-4-28.
//

#ifndef SORTALGORITHMS_HEAPSORT_H
#define SORTALGORITHMS_HEAPSORT_H

#include <iostream>

using namespace std;

template <typename T>
void __shiftDown(T arr[], int n, int k) {
    while (2 * k + 1 <= n) {
        int j = 2 * k + 1;
        if (j + 1 <= n && arr[j + 1] > arr[j])
            j++;

        if (arr[k] >= arr[j])
            break;

        swap(arr[k], arr[j]);
        k = j;
    }
}

template <typename T>
void heapSort(T arr[], int n) {
    // heapify
    for (int i = (n - 1) / 2; i >= 0; --i) {
        __shiftDown(arr, n, i);
    }

    for (int i = n - 1; i > 0; --i) {
        swap(arr[0], arr[i]);
        __shiftDown(arr, i, 0);
    }
}




#endif //SORTALGORITHMS_HEAPSORT_H
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章