文章目录
算法设计与分析(王红梅、胡明)
第一部分 基础知识
第一章 算法设计基础
第二章 算法分析基础
第二部分 基本的算法设计技术
第三章 蛮力法
常见问题
顺序查找
串匹配问题
暴力匹配(BF算法):
选择排序
气泡顺序
0/1背包问题
任务分配问题
哈密顿回路问题
TSP问题
第四章 分治法
常见问题
归并排序
快速排序
最大子段和
- 划分:将数组一分为二。
- 求解子问题:对左右半部分递归调用函数,得出左、右半部分的最大子段和,leftsum、rightsum。在求跨过数组中间的最大子段和,令为midsum
- 合并:取leftsum、rightsum、midsum的三者最大值,即为所求的整个整数序列的最大子段和
代码:
int MaxSum(int a[], int l, int r){
//只有一个元素
if(l == r)
return a[l];
else{
int mid = (l+r)/2;
int leftMaxSum = MaxSum(a, l, mid);
int rightMaxSum = MaxSum(a, mid+1, r);
int midMaxSum = 0, s1 = 0, s2 = 0, rights = 0, lefts = 0;
for(int i = mid + 1; i <= r; ++i){
s1 += a[i];
rights = max(rights, s1);
}
for(int j = mid; j >= l; --j){
s2 += a[j];
lefts = max(lefts, s2);
}
midMaxSum = rights + lefts;
return max(max(leftMaxSum, rightMaxSum), midMaxSum);
}
}
复杂度:
- 时间:O(nlogn)
- 空间:O(1)
第五章 减治法
常见问题
折半查找
二叉查找树(二叉搜索树、BST)
选择问题
插入排序
略
堆排序
假币问题
第六章 动态规划法
常见问题
多源最短路径
代码:
void floyd(int arc[n][n], int dist[n][n]) {
//初始化dist矩阵
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
dist[i][j] = arc[i][j];
}
}
//进行n轮
for(int k = 0; k < n; ++k) {
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
}
最长递增子序列
最长公共子序列
0/1背包
第七章 贪心法
常见问题
图着色问题
代码:
bool OK(int G[][], int n, int i, int color[]) {
for(int j = 0; j < n; ++j) {
if(G[i][j] == 1 && color[i] == color[j])
return false;
}
return true;
}
void coloGraph(int G[][], int n) {
int color[n] = {0};//color[i]=0代表i顶点未上色,color[i]=j代表i顶点上色j
int k = 0;//当前上的颜色
int flag = 1;//1代表还有顶点未上色1
while(flag) {
k++;
flag = 0;//假设这轮能将剩下的结点都上色
for(int i = 0; i < n; ++i) {
if(color[i] == 0) {//如果顶点i未上色
color[i] = k;//尝试上色
if(!OK(G, n, i, color)) {//如果上色有冲突,取消上色,并置flag为1
flag = 1;
color[i] = 0;
}
}
}
}
}