《数据结构与算法分析(c 描述)》—— 第二章笔记

上一篇我们实现两种算法解决选择问题,这一章可以看到一个更经典的例子:最大子序列和问题。它有多种算法解决,而且效率差异非常的大。

下面我们来看问题,以及各个算法的具体实现,感受一下各个算法差异所在。

最大子序列和问题

问题描述: 给定整数 A1, A2, … , AN (可能有负数), 求 jk=iAk 的最大值(方便起见,如果所有整数都为负数,则最大子序列和为 0 )

例:
输入 -2, 11, -4, 13, -5, -1 时, 答案为 20 (从 A2 到 A4)

下面给出时间复杂度分别为 O3, O2, O1 的算法实现,附带测试程序:

#include <stdio.h>
#include <stdlib.h>

int maxsubSumO3(const int array[], int n) {
    int i, j, k;
    int thisSum, maxSum = 0;
    for (i = 0; i < n; i++) {
        for (j = i; j < n; j ++) {
            thisSum = 0;
            for (k = i; k < j; k++)
                thisSum += array[k];
            if (thisSum > maxSum)
                maxSum = thisSum;
        }
    }
    return maxSum;
}

int maxsubSumO2(const int array[], int n) {
    int i, j;
    int thisSum, maxSum = 0;
    for (i = 0; i < n; i++) {
        thisSum = 0;
        for (j = i; j < n; j++) { 
            thisSum += array[j];
            if (thisSum > maxSum)
                maxSum = thisSum;
        }
    }
    return maxSum;
}

int maxsubSumO1(int const array[], int n) {
    int j;
    int thisSum = 0, maxSum = 0;

    for (j = 0; j < n; j++) {
        thisSum += array[j];
        if (thisSum > maxSum)
            maxSum = thisSum;
        if (thisSum < 0)
            thisSum = 0;
    }
    return maxSum;
}


int main() {
    int array[10];
    for (int i = 0; i < 10; i++) {
        array[i] = ((double)rand()/RAND_MAX - 0.5) * 10;
        printf("num %d: %d\n", i, array[i]);
    }
    printf("O3 algrthorm result is :%d\n", maxsubSumO3(array, 10));
    printf("O2 algrthorm result is :%d\n", maxsubSumO2(array, 10));
    printf("O1 algrthorm result is :%d\n", maxsubSumO1(array, 10));
}

输出结果如下图所示:

《数据结构与算法分析(c 描述)》—— 第二章笔记_第1张图片

注意

对于线性时间O1算法,即书中作者所说的“扫描算法”,其实就是我们常用的动态规划。

定义b[j]为数组中前 j 个元素数组中的最大连续子序列和。

状态方程为: b[j] = max(b[j-1] + x[j] , x[j])

int maxsubSumO1(int const array[], int n) {
    int j;
    int thisSum = 0, maxSum = 0;
    for (j = 0; j < n; j++) {
        thisSum = max(thisSum + array[j], array[j]);
        maxSum = max(maxSum, thisSum);
    }
    return maxSum;
}

欧几里德算法

计算最大公因数的欧几里德算法 Gcd(m, n)

代码实现:

int Gcd(int m, int n) {
    int rem;

    while (n > 0) {
        rem = m % n;
        m = n;
        n = rem;
    }   
    return m;
}

通过不断的计算余数直到余数是0 为止,最后的非零元就是最大公因数。

你可能感兴趣的:(数据结构,算法)