分治法查找最大值和次大值
#include <stdio.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define INF 99999
void solve(int a[],int low, int high,int &max1,int &max2)
{
if(low == high)
{
max1 = a[low];
max2 = -INF;
}
else if (low == high-1)
{
max1 = max(a[low], a[high]);
max2 = min(a[low],a[high]);
}
else
{
int mid = (low + high) / 2;
int lmax1, lmax2;
solve(a, low, mid, lmax1, lmax2);
int rmax1, rmax2;
solve(a, mid + 1, high, rmax1, rmax2);
if (lmax1 > rmax1)
{
max1 = lmax1;
max2 = max(lmax2, rmax1);
}
else
{
max1 = rmax1;
max2 =max(lmax1, rmax2);
}
}
}
int main()
{
int a[] = {5, 2, 1, 4, 3};
int n = sizeof(a) / sizeof(a[0]);
int max1, max2;
solve(a, 0, n - 1, max1, max2);
printf("max1 = %d, max2 = %d\n", max1, max2);
return 0;
}
分治法查找第k小的元素
#include <stdio.h>
int QuickSelect(int a[], int s, int t, int k)
{
int i = s, j = t, tmp;
if(s < t)
{
tmp = a[s];
while ( i != j)
{
while(j > i && a[j] >= tmp)
j --;
a[i] = a[j];
while(i < j && a[i] <= tmp)
i ++;
a[j] = a[i];
}
a[i] = tmp;
if(k - 1 == i)
return a[i];
else if(k - 1 < i)
return QuickSelect(a, s, i - 1, k);
else
return QuickSelect(a, i + 1, t, k);
}
else if(s == t && s == k - 1)
return a[k - 1];
}
int main()
{
int a[] = {6, 3, 1, 5, 8, 9, 2, 7, 10, 4};
int n = sizeof(a) / sizeof(a[0]);
printf("数组a中第8小的元素为: %d\n", QuickSelect(a, 0, n - 1, 8));
return 0;
}
折半查找递归算法
#include <stdio.h>
int BinSearch(int a[], int low, int high, int k)
{
int mid;
if (low <= high)
{
mid = (low + high) / 2;
if(a[mid] == k)
return mid;
if (a[mid] > k)
return BinSearch(a, low, mid - 1, k);
else
return BinSearch(a, mid + 1, high, k);
}
else
return -1;
}
int main()
{
int n = 10, i;
int k = 6;
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
i = BinSearch(a, 0, n - 1, k);
if (i >= 0)
printf("a[%d] = %d\n", i, k);
else
printf("未找到%d元素\n", k);
return 0;
}
折半查找非递归算法
#include <stdio.h>
int BinSearch1(int a[], int n, int k)
{
int low = 0, high = n - 1, mid;
while (low <= high)
{
mid = (low + high) / 2;
if(a[mid] == k)
return mid;
if (a[mid] > k)
high = mid - 1;
else
low = mid + 1;
}
return -1;
}
int main()
{
int n = 10, i;
int k = 6;
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
i = BinSearch1(a, n, k);
if (i >= 0)
printf("a[%d] = %d\n", i, k);
else
printf("未找到%d元素\n", k);
return 0;
}
分治法求解棋盘覆盖问题
#include<stdio.h>
#define MAX 1025
int k;
int x, y;
int board[MAX][MAX];
int tile = 1;
void ChessBoard(int tr, int tc, int dr,int dc, int size)
{
if(size == 1)
return;
int t = tile ++;
int s = size / 2;
if(dr < tr + s && dc <tc + s)
ChessBoard(tr, tc, dr, dc, s);
else
{
board[tr + s - 1][tc + s - 1] = t;
ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);
}
if(dr < tr + s && dc >= tc + s)
ChessBoard(tr, tc + s, dr, dc, s);
else
{
board[tr + s - 1][tc + s] = t;
ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);
}
if(dr >= tr + s && dc < tc + s)
ChessBoard(tr+s,tc,dr,dc,s);
else
{
board[tr + s][tc + s - 1] = t;
ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);
}
if(dr >= tr + s && dc >= tc + s)
ChessBoard(tr + s, tc + s, dr, dc, s);
else
{
board[tr + s][tc + s] = t;
ChessBoard(tr + s, tc + s, tr + s, tc + s, s);
}
}
int main()
{
k = 3;
x = 1;
y = 2;
int size = 1 << k;
ChessBoard(0, 0, x, y, size);
for(int i = 0; i < size; i ++)
{
for(int j = 0; j < size; j ++)
printf("%4d", board[i][j]);
printf("\n");
}
return 0;
}
分治法求最大连续子序列和
#include <stdio.h>
long max3(long a, long b, long c)
{
if(a < b)
a = b;
if(a > c)
return a;
else
return c;
}
long MaxSubSum(int a[], int left, int right)
{
int i, j;
long maxLeftSum, maxRightSum;
long maxLeftBorderSum, leftBorderSum;
long maxRightBorderSum, rightBorderSum;
if(left == right)
{
if(a[left] > 0)
return a[left];
else
return 0;
}
int mid = (left + right) / 2;
maxLeftSum = MaxSubSum(a, left, mid);
maxRightSum = MaxSubSum(a, mid + 1, right);
maxLeftBorderSum = 0, leftBorderSum = 0;
for(i = mid; i >= left; i --)
{
leftBorderSum += a[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
maxRightBorderSum = 0, rightBorderSum = 0;
for(j = mid + 1; j <= right; j ++)
{
rightBorderSum += a[j];
if(rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
int main()
{
int a[] = {-2, 11, -4, 13, -5, -2}, n = sizeof(a) / sizeof(a[0]);
int b[] = {-6, 2, 4, -7, 5, 3, 2, -1, 6, -9, 10, -2}, m = sizeof(b) / sizeof(b[0]);
printf("a序列的最大连续子序列的和:%ld\n", MaxSubSum(a, 0, n - 1));
printf("b序列的最大连续子序列的和:%ld\n", MaxSubSum(b, 0, m - 1));
return 0;
}