赞
踩
快速排序(Quicksort)是一种常用的排序算法,它基于分治的思想。它的核心思想是选择一个基准元素,将数组划分为两个子数组,使得左边的子数组中的所有元素都小于等于基准元素,右边的子数组中的所有元素都大于基准元素,然后对这两个子数组递归地应用快速排序算法,直到整个数组有序。
面是快速排序的基本步骤:
快速排序的关键在于分区过程。常用的分区算法是Lomuto分区和Hoare分区。Lomuto分区的实现简单但效率稍低,而Hoare分区则更高效一些。
快速排序的平均时间复杂度为O(n log n),其中n是待排序数组的长度。它是一种原地排序算法,不需要额外的存储空间,因此空间复杂度为O(1)。快速排序是一种不稳定的排序算法,意味着相等元素的相对顺序在排序后可能会改变。
动画演示(来源于网络):
Lomuto分区是一种用于快速排序算法的分区方法,由C.A.R. Hoare的经典分区方法之一。Lomuto分区算法的实现相对简单,但在某些情况下效率稍低。
下面是Lomuto分区的基本步骤:
Lomuto分区的时间复杂度与快速排序相同,平均情况下为O(n log n),最坏情况下为O(n^2)(当数组已经有序或接近有序时)
Hoare分区是一种用于快速排序算法的分区方法,由快速排序的发明者之一、英国计算机科学家Tony Hoare在1960年提出。相对于Lomuto分区,Hoare分区在一些情况下能够更高效地进行数组的划分。
下面是Hoare分区的基本步骤:
Hoare分区和Lomuto分区是两种常用的分区方法,用于快速排序算法中的数组划分。它们在实现上有所不同,对比如下:
总的来说,Lomuto分区在实现上更简单,而Hoare分区在某些情况下更高效。在实际应用中,根据具体情况选择适合的分区方法可以提高快速排序算法的性能。另外,还有其他改进的分区方法,如三路快速排序(Dutch National Flag partitioning)等,可以进一步优化快速排序的性能。
#include <stdio.h>
// 交换数组中两个元素的值
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 打印数组内容
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 分区函数,将数组划分为左边小于基准元素,右边大于基准元素
int partition(int arr[], int low, int high) {
int pivot = arr[low]; // 选择第一个元素作为基准元素
int i = low + 1; // 左指针
int j = high; // 右指针
while (1) {
// 左指针向右移动,直到找到大于基准元素的位置
while (arr[i] < pivot && i <= high) {
i++;
}
// 右指针向左移动,直到找到小于基准元素的位置
while (arr[j] > pivot && j >= low + 1) {
j--;
}
if (i >= j) {
break;
}
// 交换左指针和右指针所指向的元素
swap(&arr[i], &arr[j]);
printArray(arr, high + 1); // 打印每一步的数组状态
}
// 将基准元素放到正确的位置上
swap(&arr[low], &arr[j]);
printArray(arr, high + 1); // 打印每一步的数组状态
return j; // 返回基准元素的位置
}
// 快速排序函数
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pivot_index = partition(arr, low, high); // 获取分区点
quickSort(arr, low, pivot_index - 1); // 对左子数组递归排序
quickSort(arr, pivot_index + 1, high); // 对右子数组递归排序
}
}
int main() {
int arr[] = {10, 7, 8, 9, 1, 5};
int size = sizeof(arr) / sizeof(arr[0]);
printf("Original Array: ");
printArray(arr, size);
printf("\n");
printf("Sorting Steps:\n");
quickSort(arr, 0, size - 1);
printf("\nSorted Array: ");
printArray(arr, size);
return 0;
}
#include <stdio.h>
// 枚举类型,用于表示排序步骤
enum Step
{
COMPARE,
SWAP,
PARTITION
};
// 结构体,表示数组元素
struct Element
{
int value;
enum Step step;
};
// 交换元素的值
void swap(struct Element *a, struct Element *b)
{
int temp = a->value;
a->value = b->value;
b->value = temp;
}
// 分区函数,返回分区点的索引
int partition(struct Element arr[], int low, int high)
{
int pivot = arr[high].value; // 选择最后一个元素作为基准元素
int i = (low - 1); // 分区指针,初始为低端的前一个位置
for (int j = low; j <= high - 1; j++)
{
if (arr[j].value <= pivot)
{
i++;
swap(&arr[i], &arr[j]); // 交换元素的值
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
// 快速排序函数
void quicksort(struct Element arr[], int low, int high)
{
if (low < high)
{
int pivot_index = partition(arr, low, high); // 获取分区点的索引
// 打印分区步骤
for (int i = 0; i < low; i++)
{
printf("%d ", arr[i].value);
}
printf("| ");
for (int i = low; i <= high; i++)
{
if (i == pivot_index)
{
printf("[%d] ", arr[i].value);
}
else
{
printf("%d ", arr[i].value);
}
}
printf("| ");
for (int i = high + 1; i < high; i++)
{
printf("%d ", arr[i].value);
}
printf("\n");
quicksort(arr, low, pivot_index - 1); // 递归排序左半部分
quicksort(arr, pivot_index + 1, high); // 递归排序右半部分
}
}
int main()
{
struct Element arr[] = {{7, COMPARE}, {2, COMPARE}, {5, COMPARE}, {1, COMPARE}, {8, COMPARE}, {6, COMPARE}, {3, COMPARE}, {4, COMPARE}};
int n = sizeof(arr) / sizeof(arr[0]);
printf("原始数组: ");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i].value);
}
printf("\n\n排序步骤:\n");
quicksort(arr, 0, n - 1);
printf("\n排序后的数组: ");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i].value);
}
printf("\n");
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。