1. 冒泡排序(Bubble Sort)
冒泡排序是一种简单的排序算法。这种算法会重复地遍历待排序的数组,比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。遍历数组的工作会重复进行,直到没有需要交换的元素,这意味着数组已经排序完成。
void bubbleSort(int array[], int l, int r) {
for (int i = l; i < r; ++i) {
bool isSorted = true; // 假设数组已经排序
for (int j = r; j > i; --j) {
if (array[j] < array[j - 1]) { // 如果顺序错误,则交换
swap(array[j], array[j - 1]);
isSorted = false; // 发现未排序的元素,设置为false
}
}
if (isSorted) break; // 如果没有发生交换,则数组已经排序好
}
}
2. 快速排序(Quick Sort)
快速排序是一种分治算法。它首先从数组中选取一个"基准"(pivot),然后将数组分为两个子数组:一个包含所有小于基准的元素,另一个包含所有大于基准的元素。接着对这两个子数组进行递归地排序。
int partition(int array[], int l, int r) {
int pivot = array[l]; // 选择第一个元素作为基准
while (l < r) {
while (l < r && array[r] >= pivot) r--;
array[l] = array[r];
while (l < r && array[l] <= pivot) l++;
array[r] = array[l];
}
array[l] = pivot; // 将基准值放到正确的位置
return l; // 返回基准值的位置
}
void quickSort(int array[], int l, int r) {
if (l < r) {
int pivotPos = partition(array, l, r); // 划分数组
quickSort(array, l, pivotPos - 1); // 递归排序左子数组
quickSort(array, pivotPos + 1, r); // 递归排序右子数组
}
}
3. 插入排序(Insertion Sort)
插入排序的工作方式像排序一手扑克牌。开始时,左边是已经排序的一部分,右边是未排序的一部分。每次从未排序的部分取出第一个元素,将它插入到左边已排序部分的正确位置。
void insertSort(int array[], int l, int r) {
for (int i = l + 1; i <= r; ++i) {
int j = i;
while (j > l && array[j] < array[j - 1]) { // 将array[i]插入到左边的正确位置
swap(array[j], array[j - 1]);
j--;
}
}
}
4. 选择排序(Selection Sort)
选择排序算法将数组分为两部分:已排序的和未排序的。它不断地选择未排序部分中的最小(或最大)元素,将其移动到已排序部分的末尾。
void selectSort(int array[], int l, int r) {
for (int i = l; i < r; ++i) {
int minPos = i; // 假设当前位置为最小值
for (int j = i + 1; j <= r; ++j) {
if (array[minPos] > array[j]) {
minPos = j; // 更新最小值的位置
}
}
swap(array[i], array[minPos]); // 将找到的最小值交换到已排序部分的末尾
}
}
5. 堆排序(Heap Sort)
堆排序是利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或大于)它的父节点。
void adjustDown(int array[], int l, int r) {
int father = l, son = father * 2 + 1; // 从l开始调整,son是father的左子节点
while (son <= r) {
// 选择两个子节点中较大的一个
if (son + 1 <= r && array[son] < array[son + 1]) son++;
// 如果父节点小于子节点,则需要交换
if (array[father] < array[son]) {
swap(array[father], array[son]);
father = son; // 继续向下调整
son = father * 2 + 1;
} else {
break; // 已经是大顶堆,不需要调整
}
}
}
void heapSort(int array[], int l, int r) {
// 构建大顶堆
for (int i = (r - 1) / 2; i >= l; --i) {
adjustDown(array, i, r);
}
for (int i = r; i > l; --i) {
swap(array[l], array[i]); // 将堆顶元素(最大值)与数组末尾元素交换
adjustDown(array, l, i - 1); // 重新调整为大顶堆
}
}
6. 归并排序(Merge Sort)
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。它将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
void merge(int array[], int l, int mid, int r) {
static int tempArray[MAX_SIZE]; // 用于合并的临时数组
// 将数据复制到临时数组tempArray中
for (int i = l; i <= r; ++i) {
tempArray[i] = array[i];
}
int i = l, j = mid + 1, p = l;
// 合并回到原数组
while (i <= mid && j <= r) {
if (tempArray[i] < tempArray[j]) {
array[p++] = tempArray[i++];
} else {
array[p++] = tempArray[j++];
}
}
// 将剩余的元素复制回原数组
while (i <= mid) {
array[p++] = tempArray[i++];
}
while (j <= r) {
array[p++] = tempArray[j++];
}
}
void mergeSort(int array[], int l, int r) {
if (l < r) {
int mid = (l + r) / 2;
mergeSort(array, l, mid); // 递归排序左半部分
mergeSort(array, mid + 1, r); // 递归排序右半部分
merge(array, l, mid, r); // 合并两部分
}
}
六种排序算法比较
主函数解释
在main
函数中,首先通过标准输入读取MAX_SIZE
个整数到array
数组中。然后,将这个数组的内容复制到六个不同的数组中,每个数组用于演示一个排序算法。对每个数组应用相应的排序算法后,通过标准输出打印排序后的结果。
#include <stdio.h>
#define MAX_SIZE 10 // 定义数组的最大长度
// 函数swap用于交换两个整数的值
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
// 冒泡排序算法
void bubbleSort(int array[], int l, int r) {
for (int i = l; i < r; ++i) {
bool isSorted = true;
for (int j = r; j > i; --j) {
if (array[j] < array[j - 1]) {
swap(array[j], array[j - 1]);
isSorted = false;
}
}
if (isSorted) {
break; // 如果没有发生交换,则数组已经有序
}
}
}
// 快速排序中的分区函数
int partition(int array[], int l, int r) {
int pivot = array[l];
while (l < r) {
while (l < r && array[r] >= pivot) r--;
array[l] = array[r];
while (l < r && array[l] <= pivot) l++;
array[r] = array[l];
}
array[l] = pivot;
return l;
}
// 快速排序算法
void quickSort(int array[], int l, int r) {
if (l < r) {
int pivotPos = partition(array, l, r);
quickSort(array, l, pivotPos - 1);
quickSort(array, pivotPos + 1, r);
}
}
// 插入排序算法
void insertSort(int array[], int l, int r) {
for (int i = l + 1; i <= r; ++i) {
for (int j = i; j > l && array[j] < array[j - 1]; --j) {
swap(array[j], array[j - 1]);
}
}
}
// 选择排序算法
void selectSort(int array[], int l, int r) {
for (int i = l; i < r; ++i) {
int minPos = i;
for (int j = i + 1; j <= r; ++j) {
if (array[minPos] > array[j]) {
minPos = j;
}
}
swap(array[i], array[minPos]);
}
}
// 调整堆的函数
void adjustDown(int array[], int l, int r) {
int father = l, son = father * 2 + 1;
while (son <= r) {
if (son + 1 <= r && array[son] < array[son + 1]) {
son++;
}
if (array[father] < array[son]) {
swap(array[father], array[son]);
father = son;
son = father * 2 + 1;
} else {
break;
}
}
}
// 堆排序算法
void heapSort(int array[], int l, int r) {
for (int i = (r - 1) / 2; i >= l; --i) { // 构建大顶堆
adjustDown(array, i, r);
}
for (int i = r; i > l; --i) {
swap(array[l], array[i]); // 将最大值交换到数组末尾
adjustDown(array, l, i - 1); // 调整剩余数组,使其满足大顶堆
}
}
// 归并排序中的合并函数
void merge(int array[], int l, int mid, int r) {
static int tempArray[MAX_SIZE]; // 静态数组用于合并
for (int i = l; i <= r; ++i) {
tempArray[i] = array[i];
}
int i = l, j = mid + 1, p = l;
while (i <= mid && j <= r) {
if (tempArray[i] < tempArray[j]) {
array[p++] = tempArray[i++];
} else {
array[p++] = tempArray[j++];
}
}
while (i <= mid) {
array[p++] = tempArray[i++];
}
while (j <= r) {
array[p++] = tempArray[j++];
}
}
// 归并排序算法
void mergeSort(int array[], int l, int r) {
if (l < r) {
int mid = (l + r) / 2;
mergeSort(array, l, mid);
mergeSort(array, mid + 1, r);
merge(array, l, mid, r);
}
}
int main() {
int array[MAX_SIZE]; // 定义原始数组和它的各种副本
int array1[MAX_SIZE], array2[MAX_SIZE], array3[MAX_SIZE];
int array4[MAX_SIZE], array5[MAX_SIZE], array6[MAX_SIZE];
// 读入MAX_SIZE个整数到array,并将其复制到其他数组
for (int i = 0; i < MAX_SIZE; ++i) {
scanf("%d", &array[i]);
array1[i] = array2[i] = array3[i] = array[i];
array4[i] = array5[i] = array6[i] = array[i];
}
// 对每个数组应用不同的排序算法,并打印排序后的结果
printf("冒泡排序:\n");
bubbleSort(array1, 0, MAX_SIZE - 1);
for (int i = 0; i < MAX_SIZE; ++i) {
printf(" %2d", array1[i]);
}
printf("\n");
printf("快速排序:\n");
quickSort(array2, 0, MAX_SIZE - 1);
for (int i = 0; i < MAX_SIZE; ++i) {
printf(" %2d", array2[i]);
}
printf("\n");
printf("插入排序:\n");
insertSort(array3, 0, MAX_SIZE - 1);
for (int i = 0; i < MAX_SIZE; ++i) {
printf(" %2d", array3[i]);
}
printf("\n");
printf("选择排序:\n");
selectSort(array4, 0, MAX_SIZE - 1);
for (int i = 0; i < MAX_SIZE; ++i) {
printf(" %2d", array4[i]);
}
printf("\n");
printf("堆排序:\n");
heapSort(array5, 0, MAX_SIZE - 1);
for (int i = 0; i < MAX_SIZE; ++i) {
printf(" %2d", array5[i]);
}
printf("\n");
printf("归并排序:\n");
mergeSort(array6, 0, MAX_SIZE - 1);
for (int i = 0; i < MAX_SIZE; ++i) {
printf(" %2d", array6[i]);
}
return 0;
}