shu暑期研究项目-——排序研究
#include <iostream> #include <vector> #include <chrono> #include <random> #include <ctime> #include <algorithm> using namespace std; using namespace chrono; // ============ 1. Bubble Sort ============ void bubbleSort(vector<int>& arr) { int n = arr.size(); for (int i = 0; i < n - 1; i++) { bool swapped = false; for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { swap(arr[j], arr[j + 1]); swapped = true; } } if (!swapped) break; } } // ============ 2. Selection Sort ============ void selectionSort(vector<int>& arr) { int n = arr.size(); for (int i = 0; i < n - 1; i++) { int minIdx = i; for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIdx]) { minIdx = j; } } if (minIdx != i) { swap(arr[i], arr[minIdx]); } } } // ============ 3. Quick Sort ============ int partition(vector<int>& arr, int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j < high; j++) { if (arr[j] <= pivot) { i++; swap(arr[i], arr[j]); } } swap(arr[i + 1], arr[high]); return i + 1; } void quickSort(vector<int>& arr, int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } void quickSortWrapper(vector<int>& arr) { quickSort(arr, 0, arr.size() - 1); } // ============ 4. Merge Sort ============ void merge(vector<int>& arr, int left, int mid, int right) { int n1 = mid - left + 1; int n2 = right - mid; vector<int> L(n1), R(n2); for (int i = 0; i < n1; i++) L[i] = arr[left + i]; for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; int i = 0, j = 0, k = left; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k++] = L[i++]; } else { arr[k++] = R[j++]; } } while (i < n1) arr[k++] = L[i++]; while (j < n2) arr[k++] = R[j++]; } void mergeSort(vector<int>& arr, int left, int right) { if (left < right) { int mid = left + (right - left) / 2; mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); merge(arr, left, mid, right); } } void mergeSortWrapper(vector<int>& arr) { mergeSort(arr, 0, arr.size() - 1); } // ============ Utility Functions ============ void printArray(const vector<int>& arr, const string& name = "") { if (!name.empty()) cout << name << ": "; for (int num : arr) { cout << num << " "; } cout << endl; } vector<int> copyArray(const vector<int>& src) { return vector<int>(src.begin(), src.end()); } vector<int> generateRandomArray(int size, int minVal = 1, int maxVal = 100) { vector<int> arr(size); random_device rd; mt19937 gen(rd()); uniform_int_distribution<> dis(minVal, maxVal); for (int i = 0; i < size; i++) { arr[i] = dis(gen); } return arr; } bool isSorted(const vector<int>& arr) { for (size_t i = 1; i < arr.size(); i++) { // 使用 size_t 避免警告 if (arr[i] < arr[i - 1]) return false; } return true; } void testSortingAlgorithm(void (*sortFunc)(vector<int>&), vector<int>& arr, const string& name) { vector<int> copy = copyArray(arr); auto start = high_resolution_clock::now(); sortFunc(copy); auto end = high_resolution_clock::now(); auto duration = duration_cast<microseconds>(end - start); cout << name << ":\t"; if (isSorted(copy)) { cout << "OK, "; } else { cout << "FAIL, "; } cout << "Time: " << duration.count() << " us"; cout << endl; } // ============ Main Function ============ int main() { vector<int> sizes = {10, 100, 1000, 5000, 10000}; for (int size : sizes) { cout << "\n========== Data Size: " << size << " ==========" << endl; vector<int> original = generateRandomArray(size, 1, size * 10); if (size <= 100) { cout << "Original: "; printArray(original); } testSortingAlgorithm(bubbleSort, original, "Bubble Sort"); testSortingAlgorithm(selectionSort, original, "Selection Sort"); testSortingAlgorithm(quickSortWrapper, original, "Quick Sort"); testSortingAlgorithm(mergeSortWrapper, original, "Merge Sort"); } cout << "\n========== Special Cases ==========" << endl; vector<int> sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; cout << "Sorted array: "; printArray(sorted); testSortingAlgorithm(bubbleSort, sorted, "Bubble Sort"); testSortingAlgorithm(selectionSort, sorted, "Selection Sort"); testSortingAlgorithm(quickSortWrapper, sorted, "Quick Sort"); testSortingAlgorithm(mergeSortWrapper, sorted, "Merge Sort"); vector<int> reversed = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; cout << "\nReversed array: "; printArray(reversed); testSortingAlgorithm(bubbleSort, reversed, "Bubble Sort"); testSortingAlgorithm(selectionSort, reversed, "Selection Sort"); testSortingAlgorithm(quickSortWrapper, reversed, "Quick Sort"); testSortingAlgorithm(mergeSortWrapper, reversed, "Merge Sort"); vector<int> duplicates = {5, 2, 5, 1, 3, 5, 2, 4, 1, 3}; cout << "\nDuplicates array: "; printArray(duplicates); testSortingAlgorithm(bubbleSort, duplicates, "Bubble Sort"); testSortingAlgorithm(selectionSort, duplicates, "Selection Sort"); testSortingAlgorithm(quickSortWrapper, duplicates, "Quick Sort"); testSortingAlgorithm(mergeSortWrapper, duplicates, "Merge Sort"); cout << "\n========== Algorithm Summary ==========" << endl; cout << "Algorithm\tTime\t\tSpace\t\tStable" << endl; cout << "Bubble Sort\tO(n^2)\t\tO(1)\t\tYes" << endl; cout << "Selection Sort\tO(n^2)\t\tO(1)\t\tNo" << endl; cout << "Quick Sort\tO(nlogn)\tO(logn)\t\tNo" << endl; cout << "Merge Sort\tO(nlogn)\tO(n)\t\tYes" << endl; system("pause"); return 0; }
一个测试
刻意退化快排后的结果
正序1-10000
Bubble Sort: OK, Time: 36 us
Selection Sort: OK, Time: 187132 us
Quick Sort: OK, Time: 494184 us
Merge Sort: OK, Time: 4682 us
逆序1-10000
Bubble Sort: OK, Time: 560557 us
Selection Sort: OK, Time: 183125 us
Quick Sort: OK, Time: 295989 us
Merge Sort: OK, Time: 4287 us

#include <iostream> #include <vector> #include <chrono> #include <random> #include <ctime> #include <algorithm> #include <fstream> #include <string> #include <iomanip> #include <cmath> #include <numeric> #include <direct.h> // 用于获取当前目录 #include <windows.h> // 用于获取路径 using namespace std; using namespace chrono; // ============ 获取当前工作目录(Windows) ============ string getCurrentDirectory() { char buffer[MAX_PATH]; GetCurrentDirectory(MAX_PATH, buffer); return string(buffer); } // ============ 数据结构体定义 ============ struct DataItem { int id; int age; string name; DataItem(int _id = 0, int _age = 0, string _name = "") : id(_id), age(_age), name(_name) {} }; // 按name字典序排序的比较函数 bool compareByName(const DataItem& a, const DataItem& b) { return a.name < b.name; } // 复制结构体数组 vector<DataItem> copyDataArray(const vector<DataItem>& src) { return vector<DataItem>(src.begin(), src.end()); } // 打印结构体数组(用于调试) void printDataArray(const vector<DataItem>& arr, const string& name = "") { if (!name.empty()) cout << name << ": "; for (size_t i = 0; i < min(arr.size(), size_t(10)); i++) { cout << "{" << arr[i].id << "," << arr[i].age << ",\"" << arr[i].name << "\"} "; } if (arr.size() > 10) cout << "..."; cout << endl; } // ============ 1. Bubble Sort (整数版本) ============ void bubbleSortInt(vector<int>& arr) { int n = arr.size(); for (int i = 0; i < n - 1; i++) { bool swapped = false; for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { swap(arr[j], arr[j + 1]); swapped = true; } } if (!swapped) break; } } // Bubble Sort (结构体版本) void bubbleSortStruct(vector<DataItem>& arr) { int n = arr.size(); for (int i = 0; i < n - 1; i++) { bool swapped = false; for (int j = 0; j < n - i - 1; j++) { if (arr[j + 1].name < arr[j].name) { swap(arr[j], arr[j + 1]); swapped = true; } } if (!swapped) break; } } // ============ 2. Selection Sort (整数版本) ============ void selectionSortInt(vector<int>& arr) { int n = arr.size(); for (int i = 0; i < n - 1; i++) { int minIdx = i; for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIdx]) { minIdx = j; } } if (minIdx != i) { swap(arr[i], arr[minIdx]); } } } // Selection Sort (结构体版本) void selectionSortStruct(vector<DataItem>& arr) { int n = arr.size(); for (int i = 0; i < n - 1; i++) { int minIdx = i; for (int j = i + 1; j < n; j++) { if (arr[j].name < arr[minIdx].name) { minIdx = j; } } if (minIdx != i) { swap(arr[i], arr[minIdx]); } } } // ============ 3. Quick Sort (整数版本) ============ int partitionInt(vector<int>& arr, int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j < high; j++) { if (arr[j] <= pivot) { i++; swap(arr[i], arr[j]); } } swap(arr[i + 1], arr[high]); return i + 1; } void quickSortInt(vector<int>& arr, int low, int high) { if (low < high) { int pi = partitionInt(arr, low, high); quickSortInt(arr, low, pi - 1); quickSortInt(arr, pi + 1, high); } } void quickSortIntWrapper(vector<int>& arr) { if (!arr.empty()) { quickSortInt(arr, 0, arr.size() - 1); } } // Quick Sort (结构体版本) int partitionStruct(vector<DataItem>& arr, int low, int high) { DataItem pivot = arr[high]; int i = low - 1; for (int j = low; j < high; j++) { if (arr[j].name <= pivot.name) { i++; swap(arr[i], arr[j]); } } swap(arr[i + 1], arr[high]); return i + 1; } void quickSortStruct(vector<DataItem>& arr, int low, int high) { if (low < high) { int pi = partitionStruct(arr, low, high); quickSortStruct(arr, low, pi - 1); quickSortStruct(arr, pi + 1, high); } } void quickSortStructWrapper(vector<DataItem>& arr) { if (!arr.empty()) { quickSortStruct(arr, 0, arr.size() - 1); } } // ============ 4. Merge Sort (整数版本) ============ void mergeInt(vector<int>& arr, int left, int mid, int right) { int n1 = mid - left + 1; int n2 = right - mid; vector<int> L(n1), R(n2); for (int i = 0; i < n1; i++) L[i] = arr[left + i]; for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; int i = 0, j = 0, k = left; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k++] = L[i++]; } else { arr[k++] = R[j++]; } } while (i < n1) arr[k++] = L[i++]; while (j < n2) arr[k++] = R[j++]; } void mergeSortInt(vector<int>& arr, int left, int right) { if (left < right) { int mid = left + (right - left) / 2; mergeSortInt(arr, left, mid); mergeSortInt(arr, mid + 1, right); mergeInt(arr, left, mid, right); } } void mergeSortIntWrapper(vector<int>& arr) { if (!arr.empty()) { mergeSortInt(arr, 0, arr.size() - 1); } } // Merge Sort (结构体版本) void mergeStruct(vector<DataItem>& arr, int left, int mid, int right) { int n1 = mid - left + 1; int n2 = right - mid; vector<DataItem> L(n1), R(n2); for (int i = 0; i < n1; i++) L[i] = arr[left + i]; for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; int i = 0, j = 0, k = left; while (i < n1 && j < n2) { if (L[i].name <= R[j].name) { arr[k++] = L[i++]; } else { arr[k++] = R[j++]; } } while (i < n1) arr[k++] = L[i++]; while (j < n2) arr[k++] = R[j++]; } void mergeSortStruct(vector<DataItem>& arr, int left, int right) { if (left < right) { int mid = left + (right - left) / 2; mergeSortStruct(arr, left, mid); mergeSortStruct(arr, mid + 1, right); mergeStruct(arr, left, mid, right); } } void mergeSortStructWrapper(vector<DataItem>& arr) { if (!arr.empty()) { mergeSortStruct(arr, 0, arr.size() - 1); } } // ============ 数据生成器 ============ // 1. 生成正序数据(已排序) vector<int> generateSortedData(int size) { vector<int> arr(size); for (int i = 0; i < size; i++) { arr[i] = i + 1; } return arr; } // 2. 生成逆序数据 vector<int> generateReversedData(int size) { vector<int> arr(size); for (int i = 0; i < size; i++) { arr[i] = size - i; } return arr; } // 3. 生成均匀分布数据 [1, size*4] vector<int> generateUniformData(int size) { vector<int> arr(size); random_device rd; mt19937 gen(rd()); uniform_int_distribution<> dis(1, size * 4); for (int i = 0; i < size; i++) { arr[i] = dis(gen); } return arr; } // 4. 生成正态分布数据 (mean=size/2, std=size/5) vector<int> generateNormalData(int size) { vector<int> arr(size); random_device rd; mt19937 gen(rd()); double mean = size / 2.0; double stddev = size / 5.0; normal_distribution<double> dis(mean, stddev); for (int i = 0; i < size; i++) { double val = dis(gen); val = max(1.0, min(double(size), val)); arr[i] = static_cast<int>(round(val)); } return arr; } // 5. 生成随机分布(模拟退火风格) vector<int> generateRandomData(int size) { vector<int> arr(size); for (int i = 0; i < size; i++) { arr[i] = i + 1; } random_device rd; mt19937 gen(rd()); shuffle(arr.begin(), arr.end(), gen); int numSwaps = size / 10; uniform_int_distribution<> dis(0, size - 1); for (int i = 0; i < numSwaps; i++) { int idx1 = dis(gen); int idx2 = dis(gen); swap(arr[idx1], arr[idx2]); } return arr; } // 生成结构体数组数据 vector<DataItem> generateDataItems(int size, const vector<int>& baseData) { vector<DataItem> items(size); random_device rd; mt19937 gen(rd()); uniform_int_distribution<> ageDis(1, 100); string alphabet = "abcdefghijklmnopqrstuvwxyz"; uniform_int_distribution<> letterDis(0, 25); for (int i = 0; i < size; i++) { items[i].id = i + 1; items[i].age = ageDis(gen); int nameLen = letterDis(gen) % 6 + 3; string name; for (int j = 0; j < nameLen; j++) { name += alphabet[letterDis(gen)]; } items[i].name = name; } vector<DataItem> shuffled = items; for (int i = 0; i < size; i++) { int idx = baseData[i] % size; items[i] = shuffled[idx]; } return items; } // ============ 验证函数 ============ bool verifySortedInt(const vector<int>& arr) { for (size_t i = 1; i < arr.size(); i++) { if (arr[i] < arr[i - 1]) return false; } return true; } bool verifySortedStruct(const vector<DataItem>& arr) { for (size_t i = 1; i < arr.size(); i++) { if (arr[i].name < arr[i - 1].name) return false; } return true; } // ============ 主函数 ============ int main() { // 获取当前工作目录 string currentDir = getCurrentDirectory(); cout << "当前工作目录: " << currentDir << endl; // 构建CSV文件路径(直接保存在当前目录) string csvPath = "sorting_results.csv"; // 尝试创建CSV文件 ofstream csvFile(csvPath.c_str()); if (!csvFile.is_open()) { cerr << "错误:无法创建 sorting_results.csv 文件!" << endl; cerr << "请检查是否有写入权限,或尝试以管理员身份运行。" << endl; // 尝试在桌面创建 string desktopPath = string(getenv("USERPROFILE")) + "\\Desktop\\sorting_results.csv"; cout << "尝试在桌面创建文件: " << desktopPath << endl; csvFile.open(desktopPath.c_str()); if (!csvFile.is_open()) { cerr << "仍然无法创建文件。请手动检查权限。" << endl; system("pause"); return 1; } else { csvPath = desktopPath; } } // 数据规模:2^10 到 2^18 vector<int> sizes; for (int i = 10; i <= 16; i++) { sizes.push_back(1 << i); } // 数据分布类型 vector<string> distributions; distributions.push_back("Sorted"); distributions.push_back("Reversed"); distributions.push_back("Uniform"); distributions.push_back("Normal"); distributions.push_back("Random"); // 写入CSV头 csvFile << "DataSize,Distribution,DataType,BubbleSort(us),SelectionSort(us),QuickSort(us),MergeSort(us),Degradation\n"; cout << "\n========== 开始性能测试 ==========" << endl; cout << "测试数据规模: "; for (size_t i = 0; i < sizes.size(); i++) { cout << sizes[i] << " "; } cout << endl << endl; int completedTests = 0; // 对每个数据规模进行测试 for (size_t s = 0; s < sizes.size(); s++) { int size = sizes[s]; cout << "========================================" << endl; cout << "测试数据规模: " << size << endl; cout << "========================================" << endl; // 生成各种分布的数据 vector<int> sortedData = generateSortedData(size); vector<int> reversedData = generateReversedData(size); vector<int> uniformData = generateUniformData(size); vector<int> normalData = generateNormalData(size); vector<int> randomData = generateRandomData(size); vector<vector<int> > allData; allData.push_back(sortedData); allData.push_back(reversedData); allData.push_back(uniformData); allData.push_back(normalData); allData.push_back(randomData); // 对每种分布进行测试 for (size_t d = 0; d < distributions.size(); d++) { string distName = distributions[d]; vector<int>& data = allData[d]; cout << "\n 分布: " << distName << endl; // 测试整数数组 vector<int> copy1 = data, copy2 = data, copy3 = data, copy4 = data; auto start = high_resolution_clock::now(); bubbleSortInt(copy1); auto end = high_resolution_clock::now(); long long t1 = duration_cast<microseconds>(end - start).count(); start = high_resolution_clock::now(); selectionSortInt(copy2); end = high_resolution_clock::now(); long long t2 = duration_cast<microseconds>(end - start).count(); start = high_resolution_clock::now(); quickSortIntWrapper(copy3); end = high_resolution_clock::now(); long long t3 = duration_cast<microseconds>(end - start).count(); start = high_resolution_clock::now(); mergeSortIntWrapper(copy4); end = high_resolution_clock::now(); long long t4 = duration_cast<microseconds>(end - start).count(); // 验证正确性(只对中等规模验证) if (size <= 32768) { bool v1 = verifySortedInt(copy1); bool v2 = verifySortedInt(copy2); bool v3 = verifySortedInt(copy3); bool v4 = verifySortedInt(copy4); if (!v1 || !v2 || !v3 || !v4) { cout << " 警告:某些算法排序失败!" << endl; } } // 检测退化情况 string degradation = "None"; if (distName == "Sorted" && (t1 > 1000000 || t2 > 1000000)) { degradation = "Bubble/Selection Degradation on Sorted"; } if (distName == "Reversed" && t3 > 10000000) { degradation = "QuickSort Degradation on Reversed"; } // 生成结构体数据 vector<DataItem> structData = generateDataItems(size, data); // 测试结构体数组 vector<DataItem> copy1s = structData, copy2s = structData, copy3s = structData, copy4s = structData; start = high_resolution_clock::now(); bubbleSortStruct(copy1s); end = high_resolution_clock::now(); long long t1s = duration_cast<microseconds>(end - start).count(); start = high_resolution_clock::now(); selectionSortStruct(copy2s); end = high_resolution_clock::now(); long long t2s = duration_cast<microseconds>(end - start).count(); start = high_resolution_clock::now(); quickSortStructWrapper(copy3s); end = high_resolution_clock::now(); long long t3s = duration_cast<microseconds>(end - start).count(); start = high_resolution_clock::now(); mergeSortStructWrapper(copy4s); end = high_resolution_clock::now(); long long t4s = duration_cast<microseconds>(end - start).count(); // 写入CSV - 整数数据 csvFile << size << "," << distName << ",Integer," << fixed << setprecision(3) << (double)t1 << "," << fixed << setprecision(3) << (double)t2 << "," << fixed << setprecision(3) << (double)t3 << "," << fixed << setprecision(3) << (double)t4 << "," << degradation << "\n"; // 写入CSV - 结构体数据 csvFile << size << "," << distName << ",Struct," << fixed << setprecision(3) << (double)t1s << "," << fixed << setprecision(3) << (double)t2s << "," << fixed << setprecision(3) << (double)t3s << "," << fixed << setprecision(3) << (double)t4s << "," << degradation << "\n"; // 控制台输出 cout << " 整数数组 - 冒泡: " << t1 << " us, 选择: " << t2 << " us, 快速: " << t3 << " us, 归并: " << t4 << " us" << endl; cout << " 结构体数组 - 冒泡: " << t1s << " us, 选择: " << t2s << " us, 快速: " << t3s << " us, 归并: " << t4s << " us" << endl; if (degradation != "None") { cout << " 警告: " << degradation << endl; } // 刷新CSV缓冲区,确保数据写入 csvFile.flush(); completedTests++; } cout << endl; } csvFile.close(); cout << "\n========== 测试完成 ==========" << endl; cout << "总共完成 " << completedTests << " 组测试" << endl; cout << "结果已保存到: " << csvPath << endl; cout << "\n现在运行Python脚本绘制图表:" << endl; cout << "python plot_charts.py" << endl; system("pause"); return 0; }

浙公网安备 33010602011771号