您的位置:首页 > 其它

算法导论:第一章 1.3 算法设计

2012-03-13 23:43 429 查看
回顾:算法的设计有很多方法。插入排序使用的是增量方法:在排好的字数组A[1...J-1]后,将元素A[J]插入,形成排好序的字数组A[1...J]。

1.3.1 分治法:

在本节中,我们要介绍另一种设计策略,叫做“分治法”。很多算法在结构上是递归的:为了解决一个问题,算法要一次或多次的递归调用其自身来解决相关的子问题。这些算法通常采用分支策略:讲原问题分成n个较小规模而结构与原问题相似的子问题;递归的解这些子问题,然后合并其结果就得到原问题的解。

分治模式在每一层递归上都有三个步骤:

1.分解:讲原问题分解成一系列子问题; 将n个元素分成各含n/2个元素的子序列;

2.解决:递归的解各个子问题。若子问题足够小,则直接求解; 用合并排序法对两个子序列递归的排序;

3.合并:将子问题的结果合并成原问题的解; 合并两个已排序的子序列以得到排序结果。

(搞了一个早晨终于搞出来了 )

            

static void Main(string[] args)
{
int[] a = { 5, 4, 2, };
MergeSort(a, 0, a.Length - 1);
for (int i = 0; i < a.Length; i++)
{
Console.WriteLine(a[i]);
}
Console.ReadKey();
}
public static void MergeSort(int[] A, int p, int r)
{
if (p < r)
{
int q = (p + r) / 2;
MergeSort(A, p, q);
MergeSort(A, q + 1, r);
Merge(A, p, q, r);
}
}
static void Merge(int[] a, int p, int q, int r)
{
int i, j, t;
ArrayList atemp = new ArrayList(a.Length);
for (int k = 0; k < a.Length; k++)
atemp.Add(0);

t = p;                  //序列atemp的下标计数器,从p开始
i = p;                  //左子序A[P..Q]的下标计数器,从p开始
j = q + 1;              //右子序A[Q+1..R]的下表计数器,从q+1开始
//合并序列
while (t <= r)
{
if (i <= q && (j > r || a[i] <= a[j]))
atemp[t++] = a[i++];
else
atemp[t++] = a[j++];
}
//将atemp中的序列赋值给A
for (i = p; i <= r; i++)
a[i] = Convert.ToInt32(atemp[i].ToString());
}


1.3.2 分治法分析

当一个算法中含有对其自身的递归调用时,其运行时间可以用一个递归方程或递归式来表述,该方程通过描述子问题与原问题的关系给出总的运行时间。

分治算法中的递归式基于基本模式中的三个步骤的。设T(n)为在规模n下问题的运行时间。如果n足够小,如有n<c(c为常量),则得到它的直接解的时间为常量,写Θ(1)。假设我们把原问题分成a个子问题,每个的大小是原问题的1/b。若分解该问题的合并解的时间各为D(n),递归式



-----------------------------------------------------------

合并排序算法的分析牵扯到后章的内容等后章发出后再在此处进行修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: