文件:Array.hios
#ifndef ARRAY_H #define ARRAY_H #include "Object.h" #include "Exception.h" namespace DTLib { template <typename T> class Array : public Object { public: virtual bool set(int i, const T &e) // O(1) { bool ret = ((0 <= i) && (i < length())); if (ret) { m_array[i] = e; } return ret; } virtual bool get(int i, T &e) const // O(1) { bool ret = ((0 <= i) && (i < length())); if (ret) { e = m_array[i]; } return ret; } T &operator[] (int i) // O(1) { if ((0 <= i) && (i < length())) { return m_array[i]; } else { THROW_EXCEPTION(IndexOutOfBoundsException, "Paramter i is invalid ..."); } } T operator[] (int i) const // O(1) { return const_cast<Array<T>&>(*this)[i]; } T *array() const // O(1) { return m_array; } virtual int length() const = 0; protected: T *m_array = nullptr; }; } #endif // ARRAY_H
文件:Sort.h編程
#ifndef SORT_H #define SORT_H #include "Object.h" #include "Array.h" namespace DTLib { class Sort : public Object { public: template <typename T> static void Select(T array[], int len, bool min2max = true) { for (int i=0; i<len; ++i) { int min = i; for (int j=i+1; j<len; ++j) { if ((min2max ? (array[min] > array[j]) : (array[min] < array[j]))) { min = j; } } if (min != i) { Swap(array[i], array[min]); } } } template <typename T> static void Insert(T array[], int len, bool min2max = true) { for (int i=1; i<len; ++i) { T e = array[i]; int k = i; for (int j=i-1; (j>=0) && (min2max ? (e < array[j]) : (e > array[j])); --j) { array[j+1] = array[j]; k = j; } if (i != k) { array[k] = e; } } } template <typename T> static void Bubble(T arrar[], int len, bool min2max = true) { bool exchange = true; for (int i=0; (i<len) && exchange; ++i) { exchange = false; for (int j=len-1; j>i; --j) { if (min2max ? (arrar[j] < arrar[j-1]) : (arrar[j] > arrar[j-1])) { Swap(arrar[j], arrar[j-1]); exchange = true; } } } } template <typename T> static void Shell(T array[], int len, bool min2max = true) { int d = len; do { d = d / 3 +1; for (int i=d; i<len; i+=d) { T e = array[i]; int k = i; for (int j=i-d; (j>=0) && (min2max ? (e < array[j]) : (e > array[j])); j-=d) { array[j+d] = array[j]; k = j; } if (i != k) { array[k] = e; } } }while (d > 1); } template <typename T> static void Merge(T arrar[], int len, bool min2max = true) { T *helper = new T[len]; if (helper != nullptr) { Merge(arrar, helper, 0, len-1, min2max); } delete [] helper; } template <typename T> static void Quick(T array[], int len, bool min2max = true) { Quick(array, 0, len-1, min2max); } template <typename T> static void Select(Array<T> &array, bool min2max = true) { Select(array.array(), array.length(), min2max); } template <typename T> static void Insert(Array<T> &array, bool min2max = true) { Insert(array.array(), array.length(), min2max); } template <typename T> static void Bubble(Array<T> &array, bool min2max = true) { Bubble(array.array(), array.length(), min2max); } template <typename T> static void Shell(Array<T> &array, bool min2max = true) { Shell(array.array(), array.length(), min2max); } template <typename T> static void Merge(Array<T> &array, bool min2max = true) { Merge(array.array(), array.length(), min2max); } template <typename T> static void Quick(Array<T> &array, bool min2max = true) { Quick(array.array(), array.length(), min2max); } private: Sort(); Sort(const Sort&); Sort &operator= (const Sort&); template <typename T> static void Swap(T &a, T &b) { T c(a); a = b; b = c; } template <typename T> static void Merge(T src[], T helper[], int begin, int end, bool min2max) { if (begin < end) { int mid = (begin + end) / 2; Merge(src, helper, begin, mid, min2max); Merge(src, helper, mid + 1, end, min2max); Merge(src, helper, begin, mid, end, min2max); } } template <typename T> static void Merge(T src[], T helper[], int begin, int mid, int end, bool min2max) { int i = begin; int j = mid + 1; int k = begin; while ((i <= mid) && (j <= end)) { if (min2max ? (src[i] < src[j]) : (src[i] > src[j])) { helper[k++] = src[i++]; } else { helper[k++] = src[j++]; } } while (i <= mid) { helper[k++] = src[i++]; } while (j <= end) { helper[k++] = src[j++]; } for (int i = begin; i <= end; ++i) { src[i] = helper[i]; } } template <typename T> static void Quick(T array[], int begin, int end, bool min2max) { if (begin < end) { int pivot = Partition(array, begin, end, min2max); Quick(array, begin, pivot-1, min2max); Quick(array, pivot + 1, end, min2max); } } template <typename T> static int Partition(T array[], int begin, int end, bool min2max) { T pv = array[begin]; while (begin < end) { while ((begin < end) && (min2max ? (array[end] > pv) : (array[end] < pv))) { --end; } Swap(array[begin], array[end]); while ((begin < end) && (min2max ? (array[begin] <= pv) : (array[begin] >= pv))) { ++begin; } Swap(array[begin], array[end]); } array[begin] = pv; return begin; } }; } #endif // SORT_H
文件:main.cpp數組
#include <iostream> #include "Sort.h" #include "StaticArray.h" using namespace std; using namespace DTLib; int main() { StaticArray<int, 5> sa; for (int i=0; i<sa.length(); ++i) { sa[i] = i; } Sort::Select(sa, false); for (int i=0; i<sa.length(); ++i) { cout << sa[i] << " "; } cout << endl; return 0; }
輸出:函數
4 3 2 1 0
當待排數據元素爲體積龐大的對象時,如何提升排序的效率?
void func() { struct Test : public Object { int id; int data1[1000]; double data2[500]; }; Test t[1000]; // ... Sort::Bubble(t, 1000, false); // ... }
- 排序過程當中不可避免的須要進行交換操做
- 交換操做的本質爲數據元素的相互複製
當數據元素體積龐大時,交換操做耗時巨大
通常而言,比較操做的耗時是較小的。ui
- 爲待排數據元素設置代理對象
- 對代理對象所組成的序列進行排序
- 須要訪問有序數據元素時,經過訪問代理序列完成
[無代理] 文件:main.cppthis
#include <iostream> #include <ctime> #include "Sort.h" using namespace std; using namespace DTLib; struct Test : public Object { int id; int data1[1000]; double data2[500]; bool operator < (const Test &obj) { return id < obj.id; } bool operator <= (const Test &obj) { return id <= obj.id; } bool operator > (const Test &obj) { return id > obj.id; } bool operator >= (const Test &obj) { return id >= obj.id; } }; class TestProxy : public Object { public: int id() { return m_pTest->id; } int *data1() { return m_pTest->data1; } double *data2() { return m_pTest->data2; } Test &test() const // 獲取委託者!! { return *m_pTest; } bool operator < (const TestProxy &obj) { return test() < obj.test(); } bool operator <= (const TestProxy &obj) { return test() <= obj.test(); } bool operator > (const TestProxy &obj) { return test() > obj.test(); } bool operator >= (const TestProxy &obj) { return test() >= obj.test(); } Test &operator = (Test &test) { m_pTest = &test; return test; } protected: Test *m_pTest = nullptr; }; static Test t[1000]; static TestProxy pt[1000]; int main() { clock_t begin = 0; clock_t end = 0; for (int i=0; i<1000; ++i) { t[i].id = i; pt[i] = t[i]; } begin = clock(); Sort::Bubble(t, 1000, false); end = clock(); cout << "Entrustor Time : " << end - begin << endl; begin = clock(); Sort::Bubble(pt, 1000); end = clock(); cout << "Proxy Time : " << end - begin << endl; // for (int i=0; i<1000; ++i) // { // cout << t[i].id << " " << pt[i].id() << endl; // } return 0; }
輸出:spa
Entrustor Time : 1477 Proxy Time : 17
- DTLib 中的排序類和數組類之間存在關聯關係
- 排序類可以對數組類對象進行排序
- 當排序體積龐大的都對象時,使用代理模式完成
- 代理模式的使用有效避開對象交換時的耗時操做(同時也增長了代碼的複雜度)
- 代理模式解決方案是空間換時間思想的體現
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!代理