分治算法详解:设计、实现与时间复杂度分析
分治算法详解:设计、实现与时间复杂度分析
分治算法是一种将复杂问题分解成多个规模更小的子问题,分别求解子问题,最后合并子问题的解来得到原问题解的算法。本节将以任务调度问题为例,详细讲解分治算法的设计思路、实现方法和时间复杂度分析。
1. 任务调度问题及分治算法思路
问题描述: 给定一组任务,每个任务都有开始时间和结束时间,要求在不冲突的情况下,求解可以完成的最大任务数。
分治算法求解思路:
- 按照任务结束时间从小到大排序。
- 将任务集合分成两个子集,分别求解两个子集中可以完成的最多任务数。
- 将两个子集的结果合并起来,得到整体的最优解。
- 重复步骤2和3,直到每个子集只包含一个任务。
求解过程示意图:

2. 算法程序代码及运行结果截图
#include <stdio.h>
#include <stdlib.h>
typedef struct task {
int id; // 任务编号
int start; // 任务开始时间
int end; // 任务结束时间
} Task;
int cmp(const void *a, const void *b) {
Task ta = *(Task *)a;
Task tb = *(Task *)b;
return ta.end - tb.end;
}
int conquer(Task tasks[], int start, int end) {
if (start >= end) {
return 1;
} else if (tasks[end-1].end <= tasks[start].start) {
return end - start;
} else {
int mid = (start + end) / 2;
int left = conquer(tasks, start, mid);
int right = conquer(tasks, mid, end);
return (left > right ? left : right);
}
}
int divide(Task tasks[], int n) {
return conquer(tasks, 0, n);
}
int main() {
Task tasks[] = {
{1, 9, 10},
{2, 9, 12},
{3, 10, 11},
{4, 10, 13},
{5, 11, 11},
{6, 12, 13},
{7, 13, 15},
{8, 14, 16},
{9, 15, 17},
{10, 16, 17}
};
int n = sizeof(tasks) / sizeof(Task);
qsort(tasks, n, sizeof(Task), cmp);
int maxTasks = divide(tasks, n);
printf('最多可以完成%d个任务\n', maxTasks);
return 0;
}
运行结果截图:

3. 算法时间复杂度分析
分治算法的时间复杂度分析需要考虑两个方面:
- 分解子问题的时间复杂度。
- 合并子问题的时间复杂度。
在本题中,每次将任务集合分成两个子集时需要遍历一遍集合,时间复杂度为O(n);合并子集的时间复杂度为O(1)。因此,分治算法的时间复杂度为O(n log n)。
原文地址: https://www.cveoy.top/t/topic/oR2y 著作权归作者所有。请勿转载和采集!