算法思想
本实验代码的思想是使用快速排序算法对输入数据进行排序,并在处理小规模的子数组时使用插入排序算法进行优化。
快速排序是一种分治算法,它选择一个元素作为基准(pivot),将数组分为两部分,一部分是小于基准的元素,一部分是大于基准的元素。然后对这两部分递归地应用快速排序算法,直到子数组的大小小于等于阈值k。当子数组的大小小于等于k时,使用插入排序算法对子数组进行排序。
插入排序算法是一种简单直观的排序算法,它将数组分为已排序和未排序两部分。从未排序部分选择一个元素,将其插入到已排序部分的正确位置,重复这个过程直到所有元素都被插入到已排序部分。
在本实验中,快速排序函数quickSort采用了递归的方式进行排序。当子数组的大小小于等于k时,调用插入排序函数insertionSort对子数组进行排序。这样可以在处理小规模的子数组时,避免快速排序的递归调用,提高算法的效率。
代码展示
#include <stdio.h>
#include<iostream>
#include <stdlib.h>
#include <time.h>
#include <chrono>
using namespace std;
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
/*
int partition(int arr[], int low, int high) {
//固定基准
int 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);
}
*/
/*
int partition(int arr[], int low, int high) {
// 随机选择基准
int randomIndex = low + rand() % (high - low + 1);
swap(&arr[randomIndex], &arr[high]);
int 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);
}
*/
int partition(int arr[], int low, int high) {
// 三数取中法确定基准
int mid = low + (high - low) / 2;
if (arr[low] > arr[mid]) {
swap(&arr[low], &arr[mid]);
}
if (arr[low] > arr[high]) {
swap(&arr[low], &arr[high]);
}
if (arr[mid] > arr[high]) {
swap(&arr[mid], &arr[high]);
}
int pivot = arr[mid];
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 insertionSort(int arr[], int low, int high) {
for (int i = low + 1; i <= high; i++) {
int key = arr[i];
int j = i - 1;
while (j >= low && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
void quickSort(int arr[], int low, int high, int k) {
if (low < high) {
if (high - low + 1 <= k) {
insertionSort(arr, low, high);
}
else {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1, k);
quickSort(arr, pi + 1, high, k);
}
}
}
int main() {
// 从data.txt中读取数据
FILE* fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("无法打开文件 data.txt\n");
return 1;
}
int n;
fscanf(fp, "%d", &n);
int* arr = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
fscanf(fp, "%d", &arr[i]);
}
fclose(fp);
// 使用快速排序与插入排序结合的算法对数据进行排序
int k = 20; // 设置阈值k
// 记录开始时间
auto start = chrono::high_resolution_clock::now();
quickSort(arr, 0, n - 1, k);
// 记录结束时间
auto end = chrono::high_resolution_clock::now();
// 将排序后的结果输出到sorted.txt中
FILE* fp_sorted = fopen("sorted.txt", "w");
if (fp_sorted == NULL) {
printf("无法打开文件 sorted.txt\n");
free(arr);
return 1;
}
fprintf(fp_sorted, "排序后的数组:");
for (int i = 0; i < n; i++) {
fprintf(fp_sorted, "%d ", arr[i]);
}
fclose(fp_sorted);
// 计算程序运行时间(毫秒)
chrono::duration<double, milli> elapsed = end - start;
cout << "程序运行时间: " << elapsed.count() << " 毫秒" << endl;
free(arr);
return 0;
}