#include <stdio.h>
// 定义了一个交换函数,用于交换两个整数的值。函数接受两个整数的指针作为参数。
void swap(int* a, int* b) {
// 声明一个临时变量t并把a指针所指向的值赋给它
int t = *a;
// 把b指针所指向的值赋给a指针所指向的值
*a = *b;
// 把t的值(也就是原来a的值)赋给b指针所指向的值
*b = t;
}
// 定义了一个函数用于对数组进行分割。该函数选择数组的最后一个元素作为主元(pivot)。
// 函数接受一个整数数组、一个low索引和一个high索引作为参数。
int partition(int arr[], int low, int high) {
// 主元的选择:取数组的最后一个元素作为主元
int pivot = arr[high];
// 初始化一个变量i为low-1,这将是小于主元的元素的起始索引
int i = (low - 1);
// 遍历从low到high-1的数组元素
for (int j = low; j <= high - 1; j++) {
// 如果当前元素小于主元,则把i增加1,并把i所指向的元素和j所指向的元素交换
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
// 把主元放在i+1的位置,这是小于主元的元素的结束位置
swap(&arr[i + 1], &arr[high]);
// 返回小于主元的元素的结束位置,这个位置的元素就是第k大的元素(如果存在第k大的元素的话)
return (i + 1);
}
// 定义了一个函数用于快速选择第k大的元素。函数接受一个整数数组、一个low索引和一个high索引作为参数。
int quickSelect(int arr[], int low, int high, int k) {
// 如果low和high相等,说明数组中只有一个元素,直接返回该元素
if (low == high) {
return arr[low];
}
// 选择主元并把数组分为两部分:小于主元的元素和大于主元的元素
int pi = partition(arr, low, high);
// 如果主元的位置等于k-1,那么主元就是我们要找的元素,直接返回主元
if (pi == k - 1) {
return arr[pi];
// 如果主元的位置小于k-1,那么主元左边的元素都小于我们要找的元素,可以在右边部分继续查找
} else if (pi < k - 1) {
return quickSelect(arr, pi + 1, high, k);
// 如果主元的位置大于k-1,那么主元右边的元素都大于我们要找的元素,可以在左边部分继续查找
} else {
return quickSelect(arr, low, pi - 1, k);
}
}
int main() {
int arr[] = {11,8,3,9,7,1,2,5};
int n = sizeof(arr) / sizeof(arr[0]); // 计算数组的长度,两者相除就是数组的长度。
int k = 4;
// 调用quickSelect函数查找第k大的元素并把结果存储在result变量中。
// 这里调用的quickSelect函数是针对整个数组进行查找的。数组的起始索引0和结束索引n-1
int result = quickSelect(arr, 0, n - 1, k);
printf("第%d大的元素是:%d\n", k, result);
return 0;
}