選擇排序,插入排序,並歸排序,快速排序

本文包括選擇排序,插入排序,並歸排序,快速排序。

#include <iostream>
using namespace std;

class Sort {
protected:
    void exchange(int *a, int i, int j) {
        if (i == j)
            return;

        a[i] ^= a[j];
        a[j] ^= a[i];
        a[i] ^= a[j];
    }

    virtual void _sort(int *a, int lo, int hi) = 0;

public:
    void sort(int *a, int lo, int hi) {
        if (lo >= hi || !a)
            return;

        _sort(a, lo, hi);
    }
};

class Selection : public Sort {
    int find_min(int *a, int lo, int hi) {
        int ret = lo;
        for (int i = lo + 1; i <= hi; ++i) {
            if (a[i] < a[ret])
                ret = i;
        }
        return ret;
    }

public:
    void _sort(int *a, int lo, int hi) {
        for (int i = lo; i <= hi; ++i) {
            exchange(a, i, find_min(a, i, hi));
        }
    }
};

class Insert : public Sort {
    void insert(int *a, int lo, int hi) {
        for (int i = hi; i > lo; --i) {
            if (a[i] < a[i - 1])
                exchange(a, i, i - 1);
        }
    }

protected:
    void _sort(int *a, int lo, int hi) override {
        for (int i = lo + 1; i <= hi; ++i) {
            insert(a, lo, i);
        }
    }
};

class Merge : public Sort {
    int *data;
    int capacity;

    void merge(int *a, int lo, int mid, int hi) {
        memcpy(data + lo, a + lo, (hi - lo + 1) * sizeof(int));

        int left = lo, right = mid + 1;
        for (int i = lo; i <= hi; ++i) {
            if (left > mid)
                a[i] = data[right++];
            else if (right > hi)
                a[i] = data[left++];
            else if (data[left] < data[right])
                a[i] = data[left++];
            else
                a[i] = data[right++];
        }
    }

protected:
    void _sort(int *a, int lo, int hi) override {
        int mid = (lo + hi) / 2;
        sort(a, lo, mid);
        sort(a, mid + 1, hi);
        merge(a, lo, mid, hi);
    }

public:
    explicit Merge(int capacity) : capacity(capacity) {
        data = new int[capacity];
    }
    ~Merge() {
        delete[] data;
    }

    Merge(const Merge&) = delete;
    Merge& operator=(const Merge&) = delete;
};

class Quick : public Sort {
    int partition(int *a, int lo, int hi) {
        int value = a[lo];
        int left = lo + 1, right = hi;
        while (true) {
            // 找比value大的
            while (left < hi && a[left] <= value) ++left;
            // 找比value小的
            while (right > lo && value <= a[right]) --right;
            if (left >= right) break;
            exchange(a, left, right);
        }
        // 和小的交換位置,保證小的在左邊。
        exchange(a, lo, right);
        return right;
    }
protected:
    void _sort(int *a, int lo, int hi) override {
        int pos = partition(a, lo, hi);
        sort(a, lo, pos - 1);
        sort(a, pos + 1, hi);
    }
};

bool test(Sort &sort) {
    int a[] = {2,6,4,1,3,4,3,4,6,10,1};
    int lo = 0, hi = sizeof(a)/sizeof(*a) - 1;

    sort.sort(a, lo, hi);

    for (int i = lo; i <= hi; ++i) {
        cout << a[i] << ", ";
    }
    cout << endl;

    for (int i = lo; i <= hi - 1; ++i) {
        if (a[i] > a[i + 1])
            return false;
    }

    return true;
}

int main() {
    Selection selection;
    cout << boolalpha << test(selection) << endl;
    Insert insert;
    cout << boolalpha << test(insert) << endl;
    Merge merge(100);
    cout << boolalpha << test(merge) << endl;
    Quick quick;
    cout << boolalpha << test(quick) << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章