数据结构 THU2018 - 绪论

迭代与递归

1. 减而治之

在这里插入图片描述
例. 数组翻转
在这里插入图片描述

迭代方法:

void Reverse(int *A, int low, int high){
    
    
    while(low < high){
    
    
        int tmp = A[low];
        A[low] = A[high];
        A[high] = tmp;
        low++;
        high--;
    }
}

递归方法:

void Reverse(int *A, int low, int high){
    
    
    if(low >= high)
        return;
    int tmp = A[low];
    A[low] = A[high];
    A[high] = tmp;
    low++;
    high--;
    Reverse(A, low, high);
}

2. 分而治之

例1. 总和最大区段

给定任何一个序列 A[0,n), 找出其总和最大区段,如果有多个取最小的那个。

在这里插入图片描述
每个数组的“总和最大区段”无非有三种情况:

  • 全部落在 [low, middle]
  • 全部落在 [middle+1, high]
  • 一半落在 [low, middle], 一半落在 [middle+1 , high]
int greatest_sum (int *A, int low, int high){
    
     ///left closed and right closed
   /// 终止条件 
    if(low == high)
        return A[low];
    if(low > high)
        return 0;
     分治 /
    int middle = (low + high) / 2;
     左边的最大区段 
    int greatest_left = 0,sum = 0;
    for(int pointer_i = middle; pointer_i >= low; pointer_i--){
    
    
        sum += A[pointer_i];
        if(sum > greatest_left)
            greatest_left = sum;
    }
     右边的最大区段 
    int greatest_right = 0, sum_right = 0;
    for(int pointer_i = middle+1; pointer_i <= high; pointer_i++){
    
    
        sum_right += A[pointer_i];
        if(sum_right > greatest_right)
            greatest_right = sum_right;
    }
     递归:三者取最大 
    return max(max(greatest_left+greatest_right, greatest_sum(A, middle+1, high)),greatest_sum(A,low,middle));
}

例2. 最长公共子序列

在这里插入图片描述
分析:
在这里插入图片描述
在这里插入图片描述

int lCS(string A, string B, int n, int m){
    
    
    if(n == -1 or m == -1)
        return 0;
    if (A[n] == B[m]){
    
    
        return 1+lCS(A, B, n-1, m-1);
    }
    if(A[n]!=B[m]){
    
    
        return max(lCS(A,B,n-1,m),lCS(A,B,n,m-1));
    }
}

采用记忆法,来重复利用已经计算过的值,节省运算时间:

int ** dp;
int lCS(string A, string B, int n, int m){
    
    
    if(n <= 0  or m <= 0)
        return 0;
    if (A[n] == B[m]){
    
    
        if(dp[n-1][m-1]!=-100){
    
     // already calculated
            return 1 + dp[n-1][m-1];
        }
        else {
    
     // not calculated
            dp[n-1][m-1] = lCS(A, B, n - 1, m - 1);
            return 1 + dp[n-1][m-1];
        }
    }
    if(A[n]!=B[m]){
    
    
        if(dp[n-1][m]==-100) //not in matrix
            dp[n-1][m] = lCS(A,B,n-1,m);
        if(dp[n][m-1]==-100)
            dp[n][m-1] = lCS(A,B,n,m-1);
        return max(dp[n-1][m],dp[n][m-1]);
    }
}

int main() {
    
    
    string a = "-educational";
    string b = "-advantage";
    int n = a.length()-1;
    int m = b.length()-1;
    dp = new int*[n];
    for(int i=0;i<=n;i++){
    
    
        dp[i] = new int [m];
    }
    for (int i = 0; i <= n; i++) {
    
    
        for (int j = 0; j <= m; j++){
    
    
            dp[i][j] = -100;
        }
    }
    cout<<lCS(a,b,n,m);

    for (int i = 0; i <= n; i++) {
    
    
        for (int j = 0; j <= m; j++){
    
    
            cout<<dp[i][j]<<" ";
        }
        cout<<endl;
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41332009/article/details/114629728