算法导论的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