0
点赞
收藏
分享

微信扫一扫

算法设计与分析-自用笔记

文章目录

算法设计与分析(王红梅、胡明)

第一部分 基础知识

第一章 算法设计基础

第二章 算法分析基础

第二部分 基本的算法设计技术

第三章 蛮力法

常见问题

顺序查找
串匹配问题

暴力匹配(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;
                    }
                }
            }
        }
    }
    
  • 最小生成树问题
    prim 和 dijkstra
    kruskal
    背包问题
    活动安排问题
    多机调度问题

    第三部分 基于搜索的算法设计技术

    第八章 回溯法

    常见问题

    图着色问题
    哈密顿回路
    N皇后
    作业调度问题

    第九章 分支界限法

    TSP(特别篇)

    举报

    相关推荐

    0 条评论