码迷,mamicode.com
首页 > 编程语言 > 详细

算法导论第2章 分治法与归并排序, 二分查找法

时间:2018-01-21 01:16:35      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:子序列   元素   while   序列   数组   round   sizeof   lin   语言   

分治策略:将原问题划分成n个规模较小而结构与原问题相似的子问题,然后递归地解决这些子问题,最后再合并其结果,就可以得到原问题的解。

它需要三个步骤:

  1. 分解:将原问题分解成一系列的子问题。
  2. 解决:递归地解决各个子问题。若子问题足够小,则直接求解
  3. 合并:将子问题的结果合并成原问题的解。

通过分治策略和分治步骤,可以简单地默出归并算法。

  1. 分解:将n个元素分成各自包含n/2个元素的子序列
  2. 解决:用归并排序法递归地对两个子序列进行排序。
  3. 合并:合并两个以排序的子序列,得到排序结果:
void mergeSort(int* a, int left, int right) {
  if (left+1 < right) {
    int m = left + (right - left) / 2;//分解
    mergeSort(a, left, m);//递归地对两个子序列进行排序
    mergeSort(a, m, right);
    merge(a, left, m, right);//合并
  }
}

void merge(int * a, int left, int m, int right) {
  int n1 = m - left;
  int n2 = right - m;
  int *L = new int[n1];
  int *R = new int[n2];
  //memcpy(L, a, n1 * sizeof(int));
  //memcpy(R, a+m, n2 * sizeof(int));
  for (int i = 0; i < m - left; i++) {
    L[i] = a[left+i];
  }
  for (int i = 0; i < right - m; i++) {
    R[i] = a[m+i];
  }

  int i = 0;
  int j =0;
  for (int k = left; k < right-left; k++) {
    if (L[i] <= R[j]) {
      a[k] = L[i++];
    } else {
      a[k] = R[j++];
    }
  }
  delete[]L;
  delete[]R;
}

 对于merge函数中的合并过程,有必要也用循环不变式来分析一下:

循环中不变的量是a[left...k-1] 中包含了L[0..n1], R[0..n2)中的k-left个最小元素,并且是排好序的。

在分解步骤里有个小坑:

取中通常算法是m = (left+(right-left)), 但因为编程语言的限制,如果left值非常大则m有可能会有溢出,所以改为

left + (right - left) / 2。  因为left + (right - left) / 2< right。所以只要right不溢出,m就不会溢出

归并算法的时间复杂度是O(nlgn). 因合并时使用了两个临时数组,因此空间复杂度是O(n)







同样的,二分查找也是分治法的应用。应用分治步骤,可以很容易地默出二分查找法:
int binSearch(int* a, int target,int left, int right) {
  if (right < left ) {
    return -1;
  }
  int m = 0;
  while (left < right) {
    m = left + (right - left) / 2;
    if (a[m] == target) {
    return m;
    } else if (a[m] < target) {
      left = m+1;
    } else {
      right = m;
    }
  }
  return -1;
}

 

算法导论第2章 分治法与归并排序, 二分查找法

标签:子序列   元素   while   序列   数组   round   sizeof   lin   语言   

原文地址:https://www.cnblogs.com/jackson-zhou/p/8322367.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!