算法导论的C实现——分治法求最大子数组

算法导论的C实现——分治法求最大子数组


最近打算开启新篇,仔细啃一下算法导论这本书,为以后读博打下一点基础。希望能够尽可能实现书中伪代码与历程,并且希望自己能够坚持到最后。

//main.cpp

#include <stdio.h>
#include <stdint-gcc.h>
#include <math.h>
#include "partition.h"

int main() {
    //-------------------- maximum subarray ------------------//
    //simple example
    const int Array1[11] = {-1, 10, 5, 6, -15, 2, 98, -45, 65, -65, 10};
    //4.1-1 数组中全是负数: 返回绝对值最小数
    const int Array2[11] = {-989, -10, -5, -6, -15, -2, -98, -45, -65, -89, -10};
    testFIND_MAXIMUM_SUBARRAY(Array1, 0, 10);
    //4.1-5
    testEXTEND_FIND_MAX_SUBARRAY(Array1, 11);

    return 0;
}

//partition.cpp
//
// Created by king98 on 19-4-28.
//

#include <stdio.h>
#include <stdint-gcc.h>
#include <math.h>
#include "partition.h"

//-------------------- maximum subarray ------------------//
//TEST FUNCTION
void testFIND_MAXIMUM_SUBARRAY(const int *A, uint32_t low, uint32_t high)
{
    retFIND_MAXIMUM_SUBARRAY testFIND_MAXIMUM_SUBARRAY = FIND_MAXIMUM_SUBARRAY(A, low, high);
    printf("left:%d\n", testFIND_MAXIMUM_SUBARRAY.low);
    printf("right:%d\n", testFIND_MAXIMUM_SUBARRAY.high);
    printf("sum:%d\n", testFIND_MAXIMUM_SUBARRAY.sum);
}
//FIND_MAXIMUM_SUBARRAY(A,low,high)
struct retFIND_MAXIMUM_SUBARRAY FIND_MAXIMUM_SUBARRAY(const int *A, uint32_t low, uint32_t high)
{
    struct retFIND_MAXIMUM_SUBARRAY ret{}, left{}, right{}, cross{};

    if(low==high)
    {
        ret={low, high, A[low]};
        return ret;
    }
    else
    {
        uint32_t mid = (uint32_t) floor((low+high)/2);
        left = FIND_MAXIMUM_SUBARRAY(A, low, mid);
        right = FIND_MAXIMUM_SUBARRAY(A, mid+1, high);
        cross = FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high);
        //compare left, right and crossing subarray
        if(left.sum>right.sum && left.sum>cross.sum)
        {
            return left;
        }
        else if(right.sum>left.sum && right.sum>cross.sum)
        {
            return right;
        }
        else
        {
            return cross;
        }
    }
}
//FIND_MAX_CROSSING_SUBARRAY(A,low,mid,high)
//DESC: 找到跨越中点的最大子数组
//ARGS: A--目标数组
//      low--子数组头
//      mid--子数组中点下标
//      high--子数组尾
//RETS:
struct retFIND_MAXIMUM_SUBARRAY FIND_MAX_CROSSING_SUBARRAY(const int *A, uint32_t low, uint32_t mid, uint32_t high)
{
    struct retFIND_MAXIMUM_SUBARRAY ret{};
    //calculate left sum subarray
    int left_sum = negINFINITY;
    int sum = 0;
    uint32_t max_left = 0;
    for(uint32_t i=mid; i>=low && i<=mid;i--)
    {
        sum += A[i];
        if(sum>left_sum)
        {
            left_sum = sum;
            max_left = i;
        }
    }
    //calculate right sum subarray
    int right_sum = negINFINITY;
    sum = 0;
    uint32_t max_right = 0;
    for(uint32_t i=mid+1;i<=high;i++)
    {
        sum += A[i];
        if(sum>right_sum)
        {
            right_sum = sum;
            max_right = i;
        }
    }

    ret={max_left, max_right, left_sum+right_sum};
    return ret;
}

//4.1-5
//TEST FUNCTION
void testEXTEND_FIND_MAX_SUBARRAY(const int *A, uint32_t length)
{
    retEXTEND_FIND_MAX_SUBARRAY testEXTEND_FIND_MAX_SUBARRAY{};
    testEXTEND_FIND_MAX_SUBARRAY = EXTEND_FIND_MAX_SUBARRAY(A, length);
    printf("left:%d\n", testEXTEND_FIND_MAX_SUBARRAY.low);
    printf("right:%d\n", testEXTEND_FIND_MAX_SUBARRAY.high);
    printf("sum:%d\n", testEXTEND_FIND_MAX_SUBARRAY.sum);
}
//EXTEND_FIND_MAX_SUBARRAY
struct retEXTEND_FIND_MAX_SUBARRAY EXTEND_FIND_MAX_SUBARRAY(const int *A, uint32_t length)
{
    //A[0,...0]
    retEXTEND_FIND_MAX_SUBARRAY ret={0, 0, A[0]};

    int sum;
    for(uint32_t j=1; j<length; j++)
    {
        for(uint32_t i=0; i<=j; i++)
        {
            sum = 0;
            for(uint32_t k=i; k<=j; k++)
            {
                sum += A[k];
            }
            if(sum>ret.sum)
            {
                ret.sum = sum;
                ret.low = i;
                ret.high = j;
            }
        }
    }
    return ret;
}
//partition.h
//
// Created by king98 on 19-4-28.
//

#ifndef TEST_DIVIDE_H
#define TEST_DIVIDE_H

//int == INT32
#define negINFINITY INT32_MIN
#define posINFINITY INT32_MAX

#include <stdio.h>
#include <stdint-gcc.h>
#include <math.h>

//-------------------- maximum subarray ------------------//
    //RETURN STRUCTURE
    struct retFIND_MAXIMUM_SUBARRAY{
        uint32_t low;
        uint32_t high;
        int sum;
    };
    //FUNCTION
    void testFIND_MAXIMUM_SUBARRAY(const int *A, uint32_t low, uint32_t high);
    struct retFIND_MAXIMUM_SUBARRAY FIND_MAXIMUM_SUBARRAY(const int *A, uint32_t low, uint32_t high);
    struct retFIND_MAXIMUM_SUBARRAY FIND_MAX_CROSSING_SUBARRAY(const int *A, uint32_t low, uint32_t mid, uint32_t high);

    //4.1-5
    //RETURN STRUCTURE
    struct retEXTEND_FIND_MAX_SUBARRAY{
        uint32_t low;
        uint32_t high;
        int sum;
    };
    //FUNCTION
    void testEXTEND_FIND_MAX_SUBARRAY(const int *A, uint32_t length);
    struct retEXTEND_FIND_MAX_SUBARRAY EXTEND_FIND_MAX_SUBARRAY(const int *A, uint32_t length);

#endif //TEST_DIVIDE_H

猜你喜欢

转载自blog.csdn.net/qq_39337332/article/details/89648196