分治法求众数c语言代码
时间: 2024-11-04 18:14:00 浏览: 3
分治法通常用于解决复杂问题的一种策略,通过将大问题分解成小问题,然后递归地解决这些小问题并合并结果。对于找出数组中的众数(即出现次数最多的元素),可以采用三数切分(Median of Medians)的思想,这是一种更高效的版本。
下面是一个简单的 C 语言代码示例,使用分治法寻找整数数组的众数:
```c
#include <stdio.h>
#include <stdlib.h>
// 二分查找,返回目标值的索引,如果没有则返回 -1
int binary_search(int arr[], int low, int high, int target) {
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] == target)
return mid;
else if (arr[mid] < target)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
// 三数取中,找到数组中的中间值,作为下一次划分点
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 find_majority(int arr[], int n) {
if (n <= 1)
return arr[0]; // 如果只有一个元素,那就是众数
int med_of_med = find_majority_median(arr, n);
int count = 1;
for (int i = 0; i < n; i++) {
if (arr[i] == med_of_med)
count++;
else
count--;
if (count == 0)
return med_of_med;
}
return med_of_med;
}
// 三数取中分割
int find_majority_median(int arr[], int n) {
if (n <= 5)
return quickselect(arr, 0, n - 1, n / 2); // 对较小规模数组直接排序
int left = 0, right = n - 1;
while (left < right) {
int pivot = partition(arr + left, left, right);
if (pivot == n / 2)
break;
else if (pivot > n / 2)
right = pivot - 1;
else
left = pivot + 1;
}
return arr[left];
}
// 快速选择算法,类似于快速排序,但只找到第 k 小的元素
int quickselect(int arr[], int low, int high, int k) {
if (low == high)
return arr[low];
int pivot_index = partition(arr, low, high);
if (k == pivot_index)
return arr[k];
else if (k < pivot_index)
return quickselect(arr, low, pivot_index - 1, k);
else
return quickselect(arr, pivot_index + 1, high, k);
}
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int arr[] = {3, 2, 3, 1, 2, 4, 2, 5, 2};
int n = sizeof(arr) / sizeof(arr[0]);
printf("众数是: %d\n", find_majority(arr, n));
return 0;
}
```
这个代码首先实现了快速选择算法(quickselect)来找到数组的一个中间值,然后再利用分治思想递归地查找众数。注意,这不是最高效的方法,实际应用中哈希表或频数统计会更常用,但对于教学演示,这是一个清晰的例子。
阅读全文