# Different Sorting Time Test: ## Insertion sort, Counting sort, Merge sort, and Quick sort ( Lomuto, Hoare, Three way Partition ) 程式碼: ```cpp= #include<iostream> #include<vector> #include<time.h> #include<algorithm> using namespace std; enum type{ Lomuto = 0, Hoare, Three_Way }; static int partition_Type = 0; const int Max = 1000; void printArray(vector<int> &arr, int n); void insertionSort(vector<int> &arr, int n) { int i, key, j; for (i = 1; i < n; i++) { key = arr[i]; j = i - 1; // Move elements of arr[0..i-1], // that are greater than key, to one // position ahead of their // current position while (j >= 0 && arr[j] > key) { arr[j + 1] = arr[j]; j = j - 1; } arr[j + 1] = key; } } void Merge(std::vector<int> &Array, int front, int mid, int end){ // 利用 std::vector 的constructor, // 把array[front]~array[mid]放進 LeftSub[] // 把array[mid+1]~array[end]放進 RightSub[] std::vector<int> LeftSub(Array.begin()+front, Array.begin()+mid+1), RightSub(Array.begin()+mid+1, Array.begin()+end+1); LeftSub.insert(LeftSub.end(), Max); // 在LeftSub[]尾端加入值為 Max 的元素 RightSub.insert(RightSub.end(), Max); // 在RightSub[]尾端加入值為 Max 的元素 int idxLeft = 0, idxRight = 0; for (int i = front; i <= end; i++) { if (LeftSub[idxLeft] <= RightSub[idxRight] ) { Array[i] = LeftSub[idxLeft]; idxLeft++; } else{ Array[i] = RightSub[idxRight]; idxRight++; } } } void MergeSort(std::vector<int> &array, int front, int end){ // front與end為矩陣範圍 if (front < end) { // 表示目前的矩陣範圍是有效的 int mid = (front+end)/2; // mid即是將矩陣對半分的index MergeSort(array, front, mid); // 繼續divide矩陣的前半段subarray MergeSort(array, mid+1, end); // 繼續divide矩陣的後半段subarray Merge(array, front, mid, end); // 將兩個subarray做比較, 並合併出排序後的矩陣 } } void countSort(vector<int>& arr) { int max = *max_element(arr.begin(), arr.end()); int min = *min_element(arr.begin(), arr.end()); int range = max - min + 1; vector<int> count(range), output(arr.size()); for (int i = 0; i < arr.size(); i++) count[arr[i] - min]++; for (int i = 1; i < count.size(); i++) count[i] += count[i - 1]; for (int i = arr.size() - 1; i >= 0; i--) { output[count[arr[i] - min] - 1] = arr[i]; count[arr[i] - min]--; } for (int i = 0; i < arr.size(); i++) arr[i] = output[i]; } int Lomuto_partition(vector<int> &arr, int low, int high); int Hoare_partition(vector<int> &arr, int low, int high); void Three_Way_partition(vector<int> &arr, int l, int r, int& i, int& j); void quickSort(vector<int> &arr, int low, int high) { if (low < high) { ///Lomuto partition if(partition_Type == Lomuto){ /* pi is partitioning index, arr[p] is now at right place */ int pi = Lomuto_partition(arr, low, high); // Separately sort elements before // partition and after partition quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } ///Hoare partition else if(partition_Type == Hoare){ /* pi is partitioning index, arr[p] is now at right place */ int pi = Hoare_partition(arr, low, high); // Separately sort elements before // partition and after partition quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } ///Three way partition else if(partition_Type == Three_Way){ /* i,j is partitioning index, arr[p] is now at right place */ int i, j; // Note that i and j are passed as reference Three_Way_partition(arr, low, high, i, j); // Separately sort elements before // partition and after partition quickSort(arr, low, j); quickSort(arr, i, high); } } } int Lomuto_partition(vector<int> &arr, int low, int high) { int pivot = arr[high]; // pivot int i = (low - 1); // Index of smaller element for (int j = low; j <= high- 1; j++) { // If current element is smaller than or // equal to pivot if (arr[j] <= pivot) { i++; // increment index of smaller element swap(arr[i], arr[j]); } } swap(arr[i + 1], arr[high]); return (i + 1); } int Hoare_partition(vector<int> &arr, int low, int high) { int pivot = arr[low]; int i = low - 1, j = high + 1; while (true) { // Find leftmost element greater than // or equal to pivot do { i++; } while (arr[i] < pivot); // Find rightmost element smaller than // or equal to pivot do { j--; } while (arr[j] > pivot); // If two pointers met. if (i >= j) return j; swap(arr[i], arr[j]); } } void Three_Way_partition(vector<int> &arr, int l, int r, int& i, int& j) { i = l - 1, j = r; int p = l - 1, q = r; int v = arr[r]; while (true) { // From left, find the first element greater than // or equal to v. This loop will definitely // terminate as v is last element while (arr[++i] < v) ; // From right, find the first element smaller than // or equal to v while (v < arr[--j]) if (j == l) break; // If i and j cross, then we are done if (i >= j) break; // Swap, so that smaller goes on left greater goes // on right swap(arr[i], arr[j]); // Move all same left occurrence of pivot to // beginning of array and keep count using p if (arr[i] == v) { p++; swap(arr[p], arr[i]); } // Move all same right occurrence of pivot to end of // array and keep count using q if (arr[j] == v) { q--; swap(arr[j], arr[q]); } } // Move pivot element to its correct index swap(arr[i], arr[r]); // Move all left same occurrences from beginning // to adjacent to arr[i] j = i - 1; for (int k = l; k < p; k++, j--) swap(arr[k], arr[j]); // Move all right same occurrences from end // to adjacent to arr[i] i = i + 1; for (int k = r - 1; k > q; k--, i++) swap(arr[i], arr[k]); } int main(){ int power_of_2; do { cout<<"Enter a number(0~20)"<<endl; cin>>power_of_2; }while(power_of_2>30); unsigned int num = 1<<power_of_2; cout<<power_of_2<<": "<<num<<endl; vector<int> vec[10]; for(int i=0 ; i<10 ; ++i){ int countn = num; while(countn--){ int temp = rand()%1000; vec[i].push_back(temp); } } clock_t start_t, end_t, average = 0; for(int i =0 ; i<10 ; ++i){ start_t = clock(); //insertionSort(vec[i],num); //MergeSort(vec[i], 0, num-1); //countSort(vec[i]); { //partition_Type = Lomuto; //partition_Type = Hoare; partition_Type = Three_Way; quickSort(vec[i], 0, num-1); } end_t = clock(); average+=(end_t-start_t); } if(power_of_2<=10){ for(int i =0 ; i<10 ; ++i){ printArray(vec[i],num); } } cout<<average/10.0<<"ms"<<endl; } // A utility function to print an array // of size n void printArray(vector<int> &arr, int n) { int i; for (i = 0; i < n; i++) cout << arr[i] << " "; cout << endl; } ```