分治法(归并排序,X^n以及斐波那契数列)

来源:互联网 发布:消防防毒面具品牌知乎 编辑:程序博客网 时间:2024/06/18 16:28

分治法是解决问题的一种很好的思路,下面通过三种算法来了解分治法

public class DivideMethod {/** * 归并排序:归并算法的中心是归并两个已经有序的数组,并且递归调用归并操作。 优点和缺点:比简单排序在速度上快很多;归并排序会占用双倍的存储空间。 * 效率:归并排序的时间复杂度是 O(N*LogN);简单排序的复杂度是O(N2)。 每一趟归并的时间复杂度为 O(n), 需要O(logn)次归并 */public void mergeSort(int[] list) {int[] temp = new int[list.length];// 临时数组divideMergeSort(list, temp, 0, list.length - 1);}// 递归分割数据到基本单位private void divideMergeSort(int[] list, int[] temp, int low, int upper) {if (low == upper) {return;} else {int mid = (low + upper) / 2;divideMergeSort(list, temp, low, mid);divideMergeSort(list, temp, mid + 1, upper);merge(list, temp, low, mid + 1, upper);}}// 归并操作将基本单位归并成整个有序的数组private void merge(int[] list, int[] temp, int left, int right, int last) {int j = 0;int lowIndex = left;int mid = right - 1;int n = last - lowIndex + 1;while (left <= mid && right <= last) {if (list[left] < list[right]) {temp[j++] = list[left++];} else {temp[j++] = list[right++];}}while (left <= mid) {temp[j++] = list[left++];}while (right <= last) {temp[j++] = list[right++];}for (j = 0; j < n; j++) {list[lowIndex + j] = temp[j];}}/** * x^n的分治法策略 * x^n通过分治法可以转换为x^(n/2)*x^(n/2) 这种装换就会变成两个x^(n/2)的问题,并且两个问题是一样的,所以我们只需要解决一个问题就可以了, * 所以时间复杂度就会从O(n)变为 O(LogN) */public int devideXToN(int x,int n){if(n==0){return 1;}if(n==1){return x; }else{if(n%2==1){return devideXToN(x, n / 2) * devideXToN(x, n / 2) * x;}else{return devideXToN(x, n / 2) * devideXToN(x, n / 2);  }}}/** * 斐波那契数列是  *  f(0)=0  n=0 *  f(1)=1  n=1 *  f(n-1)+f(n-2) n>1 *   *  如果采用递归求数列,有很多数字需要重复计算多次,采用分治法可以避免重复计算, *  使计算的时间复杂段由指数级变为线性的O(n) * @param n */public int fibonacci(int n){int rs = 1;int f1=1;int f2=1;if(n<2){return 1;}//通过保存中间结果的方法可以避免多次的重复计算for(int i=2;i<n;i++){rs = f1+f2;f1=f2;f2=rs;}return rs;}}