分治算法

算法思想 - Divide and Conquer

  • Divide:把问题划分成二到多个子问题
  • Conquer: 解决每一个子问题
  • Combine: 把每个子问题的解合并成主问题的解
  • 适用于问题被划分到足够小的时候非常容易解决的情况

应用举例

多项式相乘

Divide 策略:
如何把 n 次多项式拆分成任务量接近的两个子多项式呢?
A ( x ) = a 0 + a 1 x + a 2 x 2 + . . . . + a n x n 令 : A 0 ( x ) = a 0 + a 1 x + . . . . + a n − 1 2 x n − 1 2 A 1 ( x ) = a n 2 + . . . + a n x n 2 则   A ( x ) = A 0 ( x ) + A 1 ( x ) ∗ x n 2 故问题可以改写为 A ( x ) B ( x ) = A 0 ( x ) B 0 ( x ) + A 0 ( x ) B 1 ( x ) x n 2 + A 1 ( x ) B 0 ( x ) x n 2 + A 1 ( x ) B 1 ( x ) = A 0 ( x ) B 0 ( x ) + ( A 0 ( x ) B 1 ( x ) + A 1 ( x ) B 0 ( x ) ) x n 2 + A 1 ( x ) B 1 ( x ) A(x) = a_0 + a_1x + a_2x^2 + .... + a_nx^n \\ 令: A_0(x) = a_0 + a_1x + .... + a_\frac{n-1}{2}x^\frac{n-1}{2} \\ A_1(x) = a_\frac{n}{2} + ... +a_n x^\frac{n}{2} \\ 则 \space A(x) = A_0(x) + A_1(x) * x^\frac{n}{2} \\ \textbf{故问题可以改写为} \\ A(x)B(x) = A_0(x)B_0(x) + A_0(x)B_1(x)x^\frac{n}{2} + A_1(x)B_0(x)x^\frac{n}{2} + A_1(x)B_1(x) \\ =A_0(x)B_0(x) + (A_0(x)B_1(x) + A_1(x)B_0(x))x^\frac{n}{2} + A_1(x)B_1(x) A(x)=a0+a1x+a2x2+....+anxnA0(x)=a0+a1x+....+a2n1x2n1A1(x)=a2n+...+anx2n A(x)=A0(x)+A1(x)x2n故问题可以改写为A(x)B(x)=A0(x)B0(x)+A0(x)B1(x)x2n+A1(x)B0(x)x2n+A1(x)B1(x)=A0(x)B0(x)+(A0(x)B1(x)+A1(x)B0(x))x2n+A1(x)B1(x)
divide 策略优化:
在上面的步骤中,我们将要进行四次 T(n/2) 的乘法运算,而我们可以观察到
A 0 ( x ) B 1 ( x ) + A 1 ( x ) B 0 ( x ) = ( A 0 ( x ) + A 1 ( x ) ) ( B 0 ( x ) + B 1 ( x ) ) − A 0 ( x ) B 0 ( x ) − A 1 ( x ) B 1 ( x ) A_0(x)B_1(x) + A_1(x)B_0(x) = (A_0(x) + A_1(x))(B_0(x) + B_1(x)) - A_0(x)B_0(x) - A_1(x)B_1(x) A0(x)B1(x)+A1(x)B0(x)=(A0(x)+A1(x))(B0(x)+B1(x))A0(x)B0(x)A1(x)B1(x)
所以只需进行三次 T(n/2) 乘法运算
故整体算法如下:
在这里插入图片描述

快速排序

Divide 策略:先花 O(n) 的时间为数组中某一个的元素(可以为队首、队尾、随机元素)找好他应该在的位置,再根据他的位置把数组分为两个部分(一部分都比他小,一部分都比他大)。

以队尾元素为例,其分块算法如下:

// Input A[p....r]
x = A[r];
i = p - 1;
for (j = p; j <= r-1; j++) {
    if (A[j] <= x) {
        i++;
        swap(i, j);
    }
}
swap(i+1, r);
return i+1;

图解演示
在这里插入图片描述
因为 A[j] < A[r],所以 i++ A[j] 和 A[i] 交换(刚好是它自己)
在这里插入图片描述
因为 A[j] > A[r],所以 i 不变 j 继续遍历,A[j] = 7 的时候也同理
在这里插入图片描述
因为 A[j] < A[r],所以 i++ 交换 A[i] 和 A[j],也就是把 1 放到前面那个部分去。
在这里插入图片描述
所以整体算法

// quicksort(A, p, r)
if p < r:
    q = Partition(A, p, r)
    quicksort(A, p, q - 1)
    quicksort(A, q + 1, r)
end
return A
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值