zoukankan      html  css  js  c++  java
  • 重看算法 -- 递归与分治

    递归

    典型的斐波那契数列

    f(n) = f(n-1) + f(n-2)

    分治

    二分查找

    已排好序的数组查找一个数

    使用分治的策略

    复杂度为O(logn)

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 //在数组a[left...right]中查找元素x
     6 int search(int a[], int x, int left, int right){
     7     int mid;
     8     if (left > right) return -1;//当查找完数组中都没有找到元素时, 返回-1 
     9     mid = (left + right) >> 1;  //整体右移一位,相当于除以2 
    10     if (a[mid] == x) return mid;
    11     if (a[mid] > x) return search(a, x, left, mid - 1);
    12     if (a[mid] < x)return search(a, x, mid + 1, right);
    13     
    14 } 
    15 
    16 int main(){
    17     int n, x;
    18     cin >> n;
    19 //    x = n >> 1;
    20 //    cout << x; 
    21     int a[n];
    22     for(int i = 0; i < n; i++)
    23         cin >> a[i];
    24     
    25     cin >> x;
    26     cout << search(a, x, 0, n - 1) << endl;
    27 }
    28 
    29 /*
    30 9
    31 1 2 3 4 5 6 7 8 9
    32 5
    33 */

    快速排序

    利用互相逼近的方法

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int partition(int a[], int l, int r){
     5     int i = l, j = r + 1;
     6     int x = a[i];
     7     while(true){
     8         while(a[++i] < x && i < r);
     9         while(a[--j] > x);
    10         if(i >= j) break;
    11         swap(a[i], a[j]);
    12     }
    13     a[l] = a[j];
    14     a[j] = x;
    15     return j;    
    16 }
    17 
    18 void quick(int a[], int l, int r){
    19     if(l < r){
    20         int i = partition(a, l, r);
    21         quick(a, l, i - 1);
    22         quick(a,i + 1, r);
    23     }
    24 }
    25 int main(){
    26     int n;
    27     cin >> n;
    28     
    29     int a[n]; 
    30     for(int i = 0; i < n; i++)
    31         cin >> a[i];
    32     
    33     quick(a, 0, n-1);
    34     for(int i = 0; i < n; i++)
    35         cout << a[i] << " ";
    36 } 
    37 
    38 /*
    39 7
    40 327 47235 74 5637 28 326 759
    41 28
    42 74
    43 326
    44 327
    45 759
    46 5637
    47 47235
    48 
    49 */

    寻找第K小的数

    与快排思想相似,不过要注意分治之后第k小变成了第几小

     1 #include <iostream>
     2 using namespace std;
     3 
     4 //利用数组的第一个元素将数组划分为两部分,前面都比第一个元素小,
     5 //后面都比第一个元素大,与快速排序划分完全相同
     6 int partition(int a[], int left, int right) {
     7   int i = left + 1;
     8   int j = right;
     9   int x = a[left];
    10   while(true) {
    11     while (a[i] < x && i < right) i++;
    12     while (a[j] > x) j--;
    13     if (i >= j) break;
    14     swap(a[i], a[j]);
    15   }
    16   swap(a[left], a[j]);
    17   return j;
    18 }
    19 
    20 //在下标从left到right的数组元素中输出第K小的数
    21 int find(int num[], int left, int right, int k) {
    22     int p = partition(num, left, right); //返回划分元素的下标
    23     int n = p - left + 1; // 划分元素为第n小
    24     int t;
    25     if ( n == k)
    26         t = num[p];
    27     else if (n < k) //找右半部分的第k-n小
    28         t = find(num, p + 1, right, k - n);
    29     else //找左半部分的第k小
    30         t = find(num, left, p - 1, k);
    31 
    32     return t;
    33 }
    34 
    35 int main() {
    36     int n, k;
    37     cin >> n >> k;
    38     int num[n];
    39     for (int i = 0; i < n; i++)
    40         cin >> num[i];
    41 
    42     cout << find(num, 0, n - 1, k) << endl;
    43     return 0;
    44 }
    45 
    46 /*
    47 7 5
    48 327 47235 74 5637 28 326 759
    49 
    50 */

    今天先到这吧

    认清现实,放弃幻想。 细节决定成败,心态放好,认真学习与工作。
  • 相关阅读:
    阿里规范不建议多表Join,可这SQL要怎么写?
    SQL Server中的LEFT、RIGHT函数
    正则表达式的基本语法
    常用正则表达式
    开发中常用的正则表达式
    解读C#中的正则表达式
    wx.navigateTo、wx.redirectTo、wx.reLaunch、wx.switchTab和wx.navigateBack的区别
    强烈推荐一款图片无损压缩工具
    SQL提高查询效率的几点建议
    使用低版本的VS打开高版本项目的解决方案(以VS2008打开VS2010开发的项目为例)
  • 原文地址:https://www.cnblogs.com/jyf2018/p/14755634.html
Copyright © 2011-2022 走看看