简述快速排序算法的思想
快速排序是一种常用的排序算法,其基本思想是通过选取一个基准元素,将待排序的序列分割成两个子序列,其中一个子序列的元素均小于等于基准元素,另一个子序列的元素均大于等于基准元素,然后再对这两个子序列分别递归进行快速排序,最终得到有序序列。
![](https://i-blog.csdnimg.cn/blog_migrate/992dc040858cdd4a8b0142f41f712ebe.jpeg)
代码实现
#include <stdio.h>
void quicksort(int arr[], int left, int right) {
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2];
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
if (left < j)
quicksort(arr, left, j);
if (i < right)
quicksort(arr, i, right);
}
int main() {
int arr[] = { 5, 2, 8, 4, 9, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
int i;
printf("Original array:\n");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
quicksort(arr, 0, n - 1);
printf("\nSorted array:\n");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/eb1c716549444d19ce462795e328a9b5.png)
分治法求最大最小元素
![](https://i-blog.csdnimg.cn/blog_migrate/c5b16bab42d30f530d2014da02e0d679.jpeg)
代码实现
#include <stdio.h>
void findMinMax(int arr[], int left, int right, int* min, int* max) {
int mid, min1, max1, min2, max2;
if (left == right) {
*min = arr[left];
*max = arr[left];
return;
}
if (right == left + 1) {
if (arr[left] > arr[right]) {
*max = arr[left];
*min = arr[right];
} else {
*max = arr[right];
*min = arr[left];
}
return;
}
mid = (left + right) / 2;
findMinMax(arr, left, mid, &min1, &max1);
findMinMax(arr, mid + 1, right, &min2, &max2);
if (min1 < min2)
*min = min1;
else
*min = min2;
if (max1 > max2)
*max = max1;
else
*max = max2;
}
int main() {
int arr[] = { 5, 2, 8, 4, 9, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
int min, max;
findMinMax(arr, 0, n - 1, &min, &max);
printf("数组为:");
for(int i=0;i<6;i++){
printf("%d",arr[i]);
}
printf("\n最小元素是%d,最大元素是%d", min, max);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/82d2f6fe8f58199169217357bc02dd58.png)
3.分治法求![](https://i-blog.csdnimg.cn/blog_migrate/0f5327ce344a7e8cb1d81ad3cf9f3412.png)
![](https://i-blog.csdnimg.cn/blog_migrate/234614e55ab8d425fb069810aeac27b7.jpeg)
代码实现:
#include <stdio.h>
double power(double x, int n) {
if (n == 0) {
return 1;
}
if (n == 1) {
return x;
}
if (n < 0) {
return 1 / power(x, -n);
}
if (n % 2 == 0) {
return power(x * x, n / 2);
} else {
return x * power(x * x, (n - 1) / 2);
}
}
int main() {
double x;
int n;
printf("Enter x and n: ");
scanf("%lf %d", &x, &n);
printf("%.2lf^%d = %.2lf", x, n, power(x, n));
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/1e81a537a07a19b9ecdfe2c324ee706c.png)
在上述代码中,quicksort() 函数实现了快速排序算法,接收待排序的数组 arr[],以及数组的左右边界 left 和 right。pivot 是选取的基准元素,将数组分为小于等于 pivot 和大于等于 pivot 两个部分,并递归对这两部分进行排序。
在 main() 函数中,定义了一个整型数组 arr[],并对其进行初始化。使用 sizeof() 和 / 运算符计算出数组的长度 n,并调用 quicksort() 函数对其进行排序。最后输出排序前后的数组元素。
分治法解决循环赛日程问题(课程体会)
将2^k个选手分为两个部分,一部分为A组,另一部分为B组。将比赛日程分为k轮,每轮比赛由A组和B组各自进行,每个选手在每轮比赛中都会出现且只出现一次。具体步骤如下:
当k=1时,只有两个选手,比赛日程为第一天比赛。
当k>1时,将2^k个选手分为A组和B组,分别进行日程安排。对于A组和B组,分别递归地进行比赛日程的设计,得到A组和B组的比赛日程表。
第i轮比赛,A组中的选手与B组中的选手进行比赛,比赛的日程为将A组和B组的比赛日程表沿对角线对应的元素进行交叉。例如,在第一轮比赛中,A组的第i个选手将与B组的第i个选手进行比赛,这场比赛在A组的比赛日程表中第i行第i列,B组的比赛日程表中第i行第i列,将这两个元素交叉,就得到了这场比赛的日程。
每个选手在每轮比赛中都会出现且只出现一次,因此可以得出结论,将A组和B组的比赛日程表沿对角线对应的元素进行交叉得到的比赛日程表,也是每个选手在n-1天内与其他选手各赛一次且每天只赛一次的比赛日程表。
这种算法的时间复杂度为O(n^2),因为在每个递归层级中,我们需要将n/2个选手进行比较,因此总的递归层数为log2(n),因此总的比较次数为n×log2(n)。