c++:模板的应用
请使用函数模板,写一个能够针对所有数据类型的数据的快速排序函数,并多写几个数组做测试
#include <iostream>
#include <string>
#include <cstring>// 交换两个元素的值 - 通用模板
template <typename T>
void swap(T& a, T& b) {T temp = a;a = b;b = temp;
}// 分区操作 - 通用模板
template <typename T>
int partition(T arr[], int low, int high) {T pivot = arr[high]; // 选择最右边的元素作为基准int i = low - 1; // 小于基准的元素的索引for (int j = low; j <= high - 1; j++) {// 如果当前元素小于或等于基准if (arr[j] <= pivot) {i++; // 增加小于基准区域的索引swap(arr[i], arr[j]);}}swap(arr[i + 1], arr[high]);return i + 1;
}// 快速排序函数模板 - 通用版本
template <typename T>
void quickSort(T arr[], int low, int high) {if (low < high) {// pi是分区索引,arr[pi]现在在正确的位置int pi = partition(arr, low, high);// 分别对基准元素左右两边的子数组进行排序quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}// 为C风格字符串提供全特化的分区函数
template <>
int partition<char*>(char* arr[], int low, int high) {char* pivot = arr[high]; // 选择最右边的元素作为基准int i = low - 1; // 小于基准的元素的索引for (int j = low; j <= high - 1; j++) {// 使用strcmp比较C风格字符串if (std::strcmp(arr[j], pivot) <= 0) {i++; // 增加小于基准区域的索引swap(arr[i], arr[j]);}}swap(arr[i + 1], arr[high]);return i + 1;
}// 为C风格字符串提供全特化的快速排序函数
template <>
void quickSort<char*>(char* arr[], int low, int high) {if (low < high) {// 使用特化的partition函数int pi = partition(arr, low, high);// 递归排序子数组quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}// 打印数组元素 - 通用模板
template <typename T>
void printArray(T arr[], int size) {for (int i = 0; i < size; i++) {std::cout << arr[i] << " ";}std::cout << std::endl;
}// 为C风格字符串数组提供特化的打印函数
template <>
void printArray<char*>(char* arr[], int size) {for (int i = 0; i < size; i++) {std::cout << arr[i] << " ";}std::cout << std::endl;
}int main() {// 测试整数数组 (使用通用模板)int intArr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(intArr) / sizeof(intArr[0]);std::cout << "整数数组排序前: ";printArray(intArr, n);quickSort(intArr, 0, n - 1);std::cout << "整数数组排序后: ";printArray(intArr, n);std::cout << std::endl;// 测试浮点数数组 (使用通用模板)double doubleArr[] = {3.14, 1.59, 2.65, 0.12, 5.75};int m = sizeof(doubleArr) / sizeof(doubleArr[0]);std::cout << "浮点数数组排序前: ";printArray(doubleArr, m);quickSort(doubleArr, 0, m - 1);std::cout << "浮点数数组排序后: ";printArray(doubleArr, m);std::cout << std::endl;// 测试字符数组 (使用通用模板)char charArr[] = {'d', 'a', 'c', 'b', 'f', 'e'};int p = sizeof(charArr) / sizeof(charArr[0]);std::cout << "字符数组排序前: ";printArray(charArr, p);quickSort(charArr, 0, p - 1);std::cout << "字符数组排序后: ";printArray(charArr, p);std::cout << std::endl;// 测试std::string数组 (使用通用模板)std::string strArr[] = {"banana", "apple", "orange", "grape", "cherry"};int q = sizeof(strArr) / sizeof(strArr[0]);std::cout << "std::string数组排序前: ";printArray(strArr, q);quickSort(strArr, 0, q - 1);std::cout << "std::string数组排序后: ";printArray(strArr, q);std::cout << std::endl;// 测试C风格字符串数组 (使用全特化版本)char* cstrArr[] = {"banana", "apple", "orange", "grape", "cherry"};int r = sizeof(cstrArr) / sizeof(cstrArr[0]);std::cout << "C风格字符串数组排序前: ";printArray(cstrArr, r);quickSort(cstrArr, 0, r - 1); // 调用特化版本std::cout << "C风格字符串数组排序后: ";printArray(cstrArr, r);return 0;
}
请使用函数模板,写一个能够针对所有数据类型的数据的快速排序,展示快排过程,并多写几个数组做测试
#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>// 全局变量,用于记录递归深度和步骤
int stepCount = 0;
int recursionDepth = 0;// 打印数组元素 - 通用模板
template <typename T>
void printArray(T arr[], int size, int low = -1, int high = -1, int pivot = -1) {std::cout << " ";for (int i = 0; i < size; i++) {// 标记当前处理范围和基准元素if (i == pivot) {std::cout << "[" << arr[i] << "] ";} else if (low != -1 && high != -1 && i >= low && i <= high) {std::cout << "<" << arr[i] << "> ";} else {std::cout << " " << arr[i] << " ";}}std::cout << std::endl;
}// 为const char*字符串数组提供特化的打印函数
template <>
void printArray<const char*>(const char* arr[], int size, int low, int high, int pivot) {std::cout << " ";for (int i = 0; i < size; i++) {// 标记当前处理范围和基准元素if (i == pivot) {std::cout << "[" << arr[i] << "] ";} else if (low != -1 && high != -1 && i >= low && i <= high) {std::cout << "<" << arr[i] << "> ";} else {std::cout << " " << arr[i] << " ";}}std::cout << std::endl;
}// 交换两个元素的值 - 通用模板
template <typename T>
void swap(T& a, T& b) {T temp = a;a = b;b = temp;
}// 分区操作并展示过程 - 通用模板
template <typename T>
int partition(T arr[], int low, int high, int size) {T pivot = arr[high]; // 选择最右边的元素作为基准int i = low - 1; // 小于基准的元素的索引std::cout << std::setw(2) << stepCount++ << ". 分区: 基准元素 = " << pivot << ", 范围: [" << low << "," << high << "]" << std::endl;std::cout << " 初始状态: ";printArray(arr, size, low, high, high);for (int j = low; j <= high - 1; j++) {// 如果当前元素小于或等于基准if (arr[j] <= pivot) {i++; // 增加小于基准区域的索引if (i != j) {swap(arr[i], arr[j]);std::cout << " 交换后: ";printArray(arr, size, low, high, high);}}}// 将基准元素放到正确的位置swap(arr[i + 1], arr[high]);std::cout << " 分区完成: ";printArray(arr, size, low, high, i + 1);std::cout << " 基准位置: " << i + 1 << std::endl << std::endl;return i + 1;
}// 为const char*提供全特化的分区函数
template <>
int partition<const char*>(const char* arr[], int low, int high, int size) {const char* pivot = arr[high]; // 选择最右边的元素作为基准int i = low - 1; // 小于基准的元素的索引std::cout << std::setw(2) << stepCount++ << ". 分区: 基准元素 = " << pivot << ", 范围: [" << low << "," << high << "]" << std::endl;std::cout << " 初始状态: ";printArray(arr, size, low, high, high);for (int j = low; j <= high - 1; j++) {// 使用strcmp比较C风格字符串if (std::strcmp(arr[j], pivot) <= 0) {i++; // 增加小于基准区域的索引if (i != j) {swap(const_cast<const char*&>(arr[i]), const_cast<const char*&>(arr[j]));std::cout << " 交换后: ";printArray(arr, size, low, high, high);}}}// 将基准元素放到正确的位置swap(const_cast<const char*&>(arr[i + 1]), const_cast<const char*&>(arr[high]));std::cout << " 分区完成: ";printArray(arr, size, low, high, i + 1);std::cout << " 基准位置: " << i + 1 << std::endl << std::endl;return i + 1;
}// 快速排序函数模板并展示过程 - 通用版本
template <typename T>
void quickSort(T arr[], int low, int high, int size) {recursionDepth++;if (low < high) {// 打印递归深度信息std::cout << "递归深度 " << recursionDepth << ": 处理子数组 [" << low << "," << high << "]" << std::endl;// pi是分区索引,arr[pi]现在在正确的位置int pi = partition(arr, low, high, size);// 分别对基准元素左右两边的子数组进行排序quickSort(arr, low, pi - 1, size);quickSort(arr, pi + 1, high, size);}recursionDepth--;
}// 测试函数
template <typename T>
void testQuickSort(T arr[], int size, const std::string& typeName) {std::cout << "================================================" << std::endl;std::cout << typeName << "数组快速排序过程展示:" << std::endl;std::cout << "初始数组: ";printArray(arr, size);std::cout << std::endl;// 重置步骤计数器stepCount = 0;recursionDepth = 0;// 执行快速排序quickSort(arr, 0, size - 1, size);std::cout << "排序完成数组: ";printArray(arr, size);std::cout << "================================================" << std::endl << std::endl;
}int main() {// 测试整数数组int intArr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(intArr) / sizeof(intArr[0]);testQuickSort(intArr, n, "整数");// 测试浮点数数组double doubleArr[] = {3.14, 1.59, 2.65, 0.12};int m = sizeof(doubleArr) / sizeof(doubleArr[0]);testQuickSort(doubleArr, m, "浮点数");// 测试字符数组char charArr[] = {'d', 'a', 'c', 'b', 'f'};int p = sizeof(charArr) / sizeof(charArr[0]);testQuickSort(charArr, p, "字符");// 测试std::string数组std::string strArr[] = {"banana", "apple", "orange", "grape"};int q = sizeof(strArr) / sizeof(strArr[0]);testQuickSort(strArr, q, "std::string");// 测试C风格字符串数组(使用const char*避免警告)const char* cstrArr[] = {"dog", "cat", "elephant", "ant"};int r = sizeof(cstrArr) / sizeof(cstrArr[0]);testQuickSort(cstrArr, r, "C风格字符串");return 0;
}