算法导论--分治法
来源:互联网 发布:tableview性能优化 编辑:程序博客网 时间:2024/06/05 15:05
分治法的思想:
分--将问题分解为规模更小的子问题;
治--将这些规模更小的子问题逐个击破;
合--将已解决的子问题合并,最终得出“母”问题的解;
例如:将一个数组A,从小到到大排序。
分治思想:我们可以将数组A分成2个数组,即A[0....A.length/2] 、A[A.length/2+1,A.length]。分别将它们进行从小到大的排序,然后在将2个数组 组合到一起,进行排序。有人要问了,为什么要这样呢?直接将他们直接进行排序不就行了吗?干嘛还要多此一举!
分析:如果直接将他们进行排序:例如,使用插入排序,那他的时间复杂度为O(n^2)。
如果使用分治思想进行排序,则它的时间复杂度为O(nlgn);所需时间将更少!那么nlgn这个时间复杂度是怎么计算出来的呢?其实这个倒是很简单 n>1,T(n)=2T(n/2)+0(n) ,如果每层时间复杂度是n,那他又几层呢?这是一个简单的等比数列,a1=1;Sn=n;q=2;算出来n=2^(x+1);当n足够大的时
候,n=2^x;所以,x=lgn. 所以总的时间复杂度为O(nlgn);
public class merge { public static void main(String[] args) { int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8,7}; print(data); mergeSort(data); System.out.println("排序后的数组:"); print(data); } public static void mergeSort(int[] data) { sort(data, 0, data.length - 1); } public static void sort(int[] data, int left, int right) { if (left >= right) return; // 找出中间索引 int center = (left + right) / 2; // 对左边数组进行递归 sort(data, left, center); // 对右边数组进行递归 sort(data, center + 1, right); // 合并 merge(data, left, center, right); print(data); } /** * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序 * * @param data * 数组对象 * @param left * 左数组的第一个元素的索引 * @param center * 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引 * @param right * 右数组最后一个元素的索引 */ public static void merge(int[] data, int left, int center, int right) { // 临时数组 int[] tmpArr = new int[data.length]; // 右数组第一个元素索引 int mid = center + 1; // third 记录临时数组的索引 int third = left; // 缓存左数组第一个元素的索引 int tmp = left; while (left <= center && mid <= right) { // 从两个数组中取出最小的放入临时数组 if (data[left] <= data[mid]) { tmpArr[third++] = data[left++]; } else { tmpArr[third++] = data[mid++]; } } // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个) while (mid <= right) { tmpArr[third++] = data[mid++]; } while (left <= center) { tmpArr[third++] = data[left++]; } // 将临时数组中的内容拷贝回原数组中 // (原left-right范围的内容被复制回原数组) while (tmp <= right) { data[tmp] = tmpArr[tmp++]; } } public static void print(int[] data) { for (int i = 0; i < data.length; i++) { System.out.print(data[i] + "\t"); } System.out.println(); } }
0 0
- 【算法导论】分治法
- 算法导论--分治法
- 算法导论:分治法(2)
- 算法导论--分治法--P17
- 算法导论之分治法
- 算法导论之分治法
- 算法导论之分治法
- 《算法导论》 2.3.1分治法
- 算法导论:分治法(1)
- [算法导论]分治法---最大子数组
- 分治法(算法导论Lec3)
- 【算法导论】03——分治法
- 【算法导论】分治法及归并排序
- 算法导论 第四章:分治法(二)
- 算法导论学习之分治法
- 【算法导论】分治策略
- 算法导论笔记一:算法设计之分治法
- 算法导论学习1--分治法计算逆序数
- OpenGL二 - 画一个五角星 pentagram
- 使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算
- JNI学习笔记——数组操作
- Dialog点击其他区域消失
- Java volatile关键字
- 算法导论--分治法
- 如何将Eclipse的中文版本转换成英文版本
- 建图方式一 之 “邻接链表”
- Apache Log4j配置说明
- Java动态绑定机制的内幕
- 经典问题石子合并(环形)DP
- MFC下拉框combo box控件实践笔记
- JavaScript中实现函数重载和参数默认值
- Android获取标题栏高度