linux设计方法,常见算法设计方法-分治法

分治法(Devide & Conquer)

1. 常见步骤

Devide

把一个问题的特殊实例划分成若干个子问题

Conquer

递归地解决每个子问题

Combine

将每个子问题的答案组合成最终答案

2. 举例分析

归并排序就是常见的一种采用“分治法”进行设计的算法,以下先给出具体的C#版代码示例

///

/// 对列表进行递归排序

///

/// 待排序数组

///

public static List Sort(List list){

if (list.Count <= 1)

return list;

var mid = list.Count/2;

var left = new List();

var right = new List();

// Devide

for (var i = 0; i < mid; i++)

left.Add(list[i]);

for (var j = mid; j < list.Count; j++)

right.Add(list[j]);

// Conquer

left = Sort(left);

right = Sort(right);

// Combine

return Merge(left, right);

}

///

/// 合并已经排序好的两个List

///

/// Left List

/// Right List

///

private static List Merge(List left, List right){

var temp = new List();

while ((left.Count > 0) && (right.Count > 0))

{

if (left[0] <= right[0])

{

temp.Add(left[0]);

left.RemoveAt(0);

}

else

{

temp.Add(right[0]);

right.RemoveAt(0);

}

}

if (left.Count > 0)

{

foreach (int item in left)

{

temp.Add(item);

}

}

if (right.Count > 0)

{

foreach (int item in right)

{

temp.Add(item);

}

}

return temp;

}

分析这个算法可以发现,归并算法的递归部分在于不断地将待排序数组分为左右两个等长的数组直至左右列表中都只含有一个元素,再继续进行Merge操作,前者递归所花费的时间可以简单表示成2T(n/2),后者排序可以认为是θ(n),则总时间可以表示成T(n)=2T(n/2)+θ(n)。

平均情况下,定义的T(n)=输入规模为n之下时所有可能输入的期望时间,θ是渐进符号一种,大家可以简单认为对于输入n,f(n)存在精确上下界

接下来在计算时间复杂度的时候,针对这个优雅的时间函数我们可以有两种解决办法,第一种是判断整个递归树的长度和叶节点的个数,第二种则是直接套用主定理公式进行分析。这里我们采用第二种主定理进行分析。

这里是对主定理的相关说明

针对T(n)=aT(n/b)+f(n)的函数式子(a≥1,b>1),我们可以知道归并排序算法的函数符合主定理的第二种情况,即如果存在常数k ≥ 0,有

f(n)=θ(n^(㏒{b}a((㏒n)^k)),则有T(n)=θ(n^(㏒{b}a((㏒n)^(k+1)))。这里的k=0,则归并算法最终的时间复杂度T(n)=θ(n㏒n)

额外补充一个二分法实例

///

/// 二分法查找

///

/// 传入的有序列表

/// 起始位置

/// 终止位置

/// 需要查找的x

/// 返回的列表索引

public static int BinarySearch(List list, int beginIndex, int endIndex, int x){

if ((x > list.LastOrDefault()) | (x < list.FirstOrDefault()))

return -1;

if (x == list[beginIndex])

return beginIndex;

if (x == list[endIndex])

return endIndex;

var mid = (beginIndex + endIndex)/2;

if (x == list[mid])

return mid;

return x > list[mid] ? BinarySearch(list, mid, endIndex, x) : BinarySearch(list, beginIndex, mid, x);

}

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值