请使用函数模板,写一个能够针对所有数据类型的数据的快速排序函数,并多写几个数组做测试
#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;
}