递归实现分治法

在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序归并排序)。

分解:把数组从中间分解为2个子数组

解决:递归解决子数组

合并:合并数据

 
 1         static void Main(string[] args)
 2         {
 3             int[] ints = { 3, 1, 5, 2, 4,9,-4 };
 4 
 5             ArrayList arr = new ArrayList(ints);
 6             Sort(arr);
 7             for (int i = 0; i < arr.Count; i++)
 8             {
 9                 Console.WriteLine(arr[i]);
10             }
11             Console.ReadLine();
12         }
13         /// <summary>
14         /// 分组排序
15         /// </summary>
16         /// <param name="arr"></param>
17         /// <returns></returns>
18         public static ArrayList Sort(ArrayList arr)
19         {
20             ArrayList arr_l = new ArrayList();
21             ArrayList arr_r = new ArrayList();
22             if (arr.Count > 1)
23             {
24                 for (int i = 0; i < arr.Count; i++)
25                 {
26                     int num = arr.Count / 2;
27 
28                     if (i < num)
29                         arr_l.Add(arr[i]);
30                     else
31                         arr_r.Add(arr[i]);
32                 }
33 
34                 ArrayList part1 = Sort(arr_l);//分组1
35                 ArrayList part2 = Sort(arr_r);//分组2
36                 Merger(part1, part2, arr);
37             }
38 
39             return arr;
40         }
41         /// <summary>
42         /// 合并
43         /// </summary>
44         /// <param name="arr_l"></param>
45         /// <param name="arr_r"></param>
46         /// <param name="arr">数据集</param>
47         public static void Merger(ArrayList arr_l, ArrayList arr_r, ArrayList arr)
48         {
49             int l = 0;//左索引
50             int r = 0;//右索引
51             int index = 0;//数据集索引
52 
53             while (l < arr_l.Count && r < arr_r.Count)
54             {
55                 if ((int)arr_l[l] <= (int)arr_r[r])
56                 {
57                     arr[index] = (int)arr_l[l];
58                     l++;
59                 }
60                 else
61                 {
62                     arr[index] = (int)arr_r[r];
63                     r++;
64                 }
65                 index++;
66             }
67             while (l < arr_l.Count)
68             {
69                 arr[index] = (int)arr_l[l];
70                 index++;
71                 l++;
72             }
73 
74             while (r < arr_r.Count)
75             {
76                 arr[index] = (int)arr_r[r];
77                 index++;
78                 r++;
79             }
80 
81         }

 

分解图

时间分析

分解:把数组从中间分解为2个子数组需要常量c

解决:递归解决规模n/2子数组需要lgn+1

合并:合并数据需要常量n

每一层运算时间为cn,总时间为cn(lgn+1);忽略常量c得到结果nlgn

 

效果图

 

 

结束语

程序存在着一些不足,操作比较复杂,时间解释一块自己也无法完美表达,也可能存在理解误差,希望给出指导意见

请多多指教!

posted @ 2017-02-13 15:28  技术大兵  阅读(399)  评论(0编辑  收藏  举报