算法设计技巧与分析笔记 第一章

1.搜索:设A【1……n】为一个n个元素的数组,判定给定元素x是否在A中

线性搜索:直接扫描A中所有项目,将每个项目与x做比较。

二分搜索

A【low……high】为有序非空数组(假定为升序),A【mid】为中间元素

假定x>A【mid】,则丢弃A【low…mid】,继续搜索A【mid+1…high】;

假定x<A【mid】,则丢弃A【mid…high】,继续搜索A【low…mid-1】;

若x=A【mid】,返回mid,结束搜索。

算法分析:时间复杂度:O(log n)

2.排序设A【1……n】为一个n个元素的数组,将A中元素进行排序

选择排序(SELECTIONSORT):

首先找到最小元素,并将其放在A【1】中,然后找到剩下n-1个元素中最小元素,放入A【2】中,重复值数列有序

元素比较次数:n(n-1)/2;

插入排序(INSERTIONSORT):

从大小为1的A【1】开始,它自然是已排序的,则接下来的第i次中,将A【i】插入到已排序的子数组A【1…i-1】中的合适位置,重复直到数列有序。

元素比较次数:n-1到n(n-1)/2之间,元素比较次数取决于输入元素的顺序;

自底向上排序(BOTTOMUPSORT):

将元素分为以1为单位的数组,先合并为一个2元素的排序序列,然后将每两个连续的2元素序列合并为大小为4的排序序列,……在第j次迭代中,合并n/2^j(下取整)对大小为2^(j-1)的排序序列,若剩余k个元素,1<=k<=2^(j-1)时,将k放在下一次合并中,若2^(j-1)<k<2^j,则将它们合并。

元素比较次数:(nlogn)/2到nlogn-n+1之间;元素比较次数与元素输入次序有关;

算法思想结合下图:

时间: 2024-11-06 10:02:02

算法设计技巧与分析笔记 第一章的相关文章

019-dfs.bfs-图的遍历-《算法设计技巧与分析》M.H.A学习笔记

深度优先搜索DFS 深搜框架: bool dfs(int loc) { 标记状态loc已访问; if (loc为目标状态) return true; for (每个可能的操作) { 对loc应用操作产生新状态nstat; if (nstat合法且未被访问) { if (dfs(nstat)) return true; } } 撤销loc已访问标记; // 这步要具体问题具体分析了 return false; } 广度优先搜索BFS 实现方法 1. 首先将根节点放入队列中. 2. 从队列中取出第一

017-Prim算法-贪心-《算法设计技巧与分析》M.H.A学习笔记

基本思路: 定义结点集合U, V (U表示已经选择加入MST的结点集合,V表示未选) 1. 任选一个结点加入U 2. 选择一条边权最小的边,他的两个结点分别属于U, V,并把属于V的那个结点加入U 3. 重复执行2直到V空 伪代码: C++代码: int g[mnx][mnx]; int n, m; int d[mnx]; // 朴素 prim, 复杂度O(|V|^2) |V|:点数, |E|:边数 int prim() { memset(d, 0x3f, sizeof d); //初始化 in

016-kruskal算法-贪心-《算法设计技巧与分析》M.H.A学习笔记

最小生成树: 在一给定的连通无向图G = (V, E)中,(u, v) 代表连接顶点u与顶点v的边,而 w(u, v)代表此边的权重,若存在T为G的子集且为无循环图,使得w(T) 最小,则此T为G的最小生成树. 基本思路: kruskal算法总共选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中.注意到所选取的边若产生环路则不可能形成一棵生成树.kruskal算法分e 步,其中e 是网络中边的数目.按耗费递增的顺序来考虑这e 条边,每次

014-背包问题-动态规划-《算法设计技巧与分析》M.H.A学习笔记

01背包: 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2--Wn,与之相对应的价值为P1,P2--Pn.求能获得的最大总价值. 基本思路: V[i,j]表示从前i件物品中取出的,能装入体积为j的背包的物品的最大总价值. 初始化条件: V[i,0]和V[0,j]都为0,我们从其意义上就可以理解. 状态转移方程: V[i,j]=max{ V[i-1,j],V[i-1,j-Wi]+Pi } ,前后分别为第i件物品不取和取得情况. 总的就是下面的递推式: 算法分析: 表

013--Floyd算法-动态规划-《算法设计技巧与分析》M.H.A学习笔记

多源最短路:有向图,求从每个顶点到其他所有顶点的最短距离. 基本思路: 假设有向图的所有点编号为1到n,l[i,j]表示从i到j的边的长度,如果不存在边,则置为正无穷. 定义d(k,i,j)表示从点i到点j,并且不经过编号大于k的点的最短距离. 初始化条件: K=0时,d(0,i,j)=l[i,j]. 状态转移方程: d(k,i,j)=min{ d(k-1,i,j),d(k-1,i,k)+d(k-1,k,j) }   1<=k<=n 于是我们有如下的递归式: 算法分析: 显然,Floyd算法的

018-Huffman树-贪心-《算法设计技巧与分析》M.H.A学习笔记

Huffman树是完全二叉树,权重较大的节点距离根较近. Huffman编码是一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字. 基本思路: 建立Huffman树的过程: 假设有n个权值,则构造出的哈夫曼树有n个叶子结点. n个权值分别设为 w1.w2.-.wn,则哈夫曼树的构造规则为: (1) 将w1.w2.-,wn看成是有n 棵树的森林(每棵树仅有一个结点): (2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左.右子树,且新树的根结点权值为其左.右子树

《数据结构与算法分析:C语言描述》复习——第十章“算法设计技巧”——Alpha-Beta剪枝

2014.07.08 22:43 简介: “搜索”与“剪枝”几乎是如影随形的.此处的“搜索”指的是带有回溯算法的深度优先搜索. 在之前的“Minimax策略”中我们给出了一个三连棋的程序,运行后你就知道计算一步棋要花多少时间. 为了计算最优的一步棋,我们可能需要递归9万多次.如果毫无疑问这种阶乘式的穷举过程必须通过剪枝来加速. 本篇介绍一种用于Minimax策略的剪枝思路——α-β剪枝. 剪枝的英语是pruning,所以不要想当然说成trimming. 图示: 在上一篇讲解Minimax策略的博

五种常用的算法设计技巧之二:分治算法

一,介绍 分治算法主要包含两个步骤:分.治.分,就是递归地将原问题分解成小问题:治则是:在解决了各个小问题之后(各个击破之后)合并小问题的解,从而得到整个问题的解 二,分治递归表达式 分治算法一般都可以写出一个递归表达式:比如经典的归并排序的递归表达式:T(N)=2T(N/2)+O(N) T(N)代表整个原问题,采用了分治解决方案后,它可以表示成: ①分解成了两个规模只有原来一半(N/2)的子问题:T(N/2) ②当解决完这两个子问题T(N/2)之后,再合并这两个子问题需要的代价是 O(N) 递

《Java并发变成实践》读书笔记---第一章 简介

<Java并发编程实战>深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册.书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险.构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁.原子变量.非阻塞算法以及