
数据结构与算法
冰阔落
Stay hungry, Stay foolish, Stop when you are perfect.
展开
-
经典谷歌面试题“扔鸡蛋”,看看你会做吗?
第二天题目:扔鸡蛋问题有2个鸡蛋,从100层楼上往下扔,以此来测试鸡蛋的硬度。比如鸡蛋在第9层没有摔碎,在第10层摔碎了,那么鸡蛋不会摔碎的临界点就是9层。问:如何用最少的尝试次数,测试出鸡蛋不会摔碎的临界点?举个栗子,最笨的测试方法,是什么样的呢?把其中一个鸡蛋,从第1层开始往下扔。如果在第1层没碎,换到第2层扔;如果在第2层没碎,换到第3层扔…….如果第59层没碎,换到第60层扔;...转载 2018-07-16 09:50:26 · 2395 阅读 · 2 评论 -
STL中map用法详解
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有转载 2014-09-03 20:19:38 · 1522 阅读 · 0 评论 -
Toposort(拓扑排序)——DFS递归回溯版
拓扑排序简单来说就是把一个图的所有节点排序,使得每一条有向边(u,v)对应的u都排在v的前面。 拓扑排序最大的用途就是判断一个有向图是否有环,当然判断还有一种方法就是Floyd算法。如果用邻接表的话拓扑排序的时间复杂度是O(N*E),邻接矩阵是O(N^2),N表示顶点数,E表示边数,Floyd时间复杂度是O(N^3)。性质1、 拓扑排序在有向无环图中才能排出有效的序列,否则能判断该转载 2014-08-18 16:23:58 · 2145 阅读 · 0 评论 -
置换表
一个多功能的数据结构 国际象棋的搜索树可以用图来表示,而置换结点可以引向以前搜索过的子树上。置换表可以用来检测这种情况,从而避免重复劳动。如果“1. e4 d6 2. d4”以后的局面已经搜索过了,那就没有必要再搜索“1. d4 d6 2. e4”以后的局面了。 这个原因可能鼓舞着早期的电脑国际象棋程序的设计师们,而现在事实上这还是置换表的次要用途。在某些局面,例如在没有通路兵的王兵残局中,转载 2014-08-29 10:04:39 · 4089 阅读 · 1 评论 -
差分约束系统
转载:http://blog.sina.com.cn/s/blog_60707c0f0100xht7.html1.问题定义 差分约束系统属于线性规划问题。在一个差分约束系统中,线性规划矩阵A的每一行包含一个1和一个-1,A的所有其他元素都为0。因此,由Ax≤b给出的约束条件是m个差分约束集合,其中包含n个未知元。每个约束条件为如下形式的简单线性不等式:xj-xi≤bk(1≤i,j≤转载 2015-02-15 21:42:59 · 1635 阅读 · 0 评论 -
欧拉路与欧拉回路
对无向图: 定义:给定无孤立结点图G,若存在一条路,经过图中每条边一次且仅仅一次,该条路称欧拉路,若存在一条回路,经过图中每边一次且仅仅一次,该回路称为欧拉回路。具有欧拉回路的图称为欧拉图,不是柏拉图。定理:无向图G具有一条欧拉路,当且仅当G是连通的,且有0个或者是两个奇数度得结点。推论:无向图G具有一条欧拉回路,当且仅当G是连通的,并且所有结点的度数均为偶数。一笔画问题就是典型的转载 2014-08-17 16:23:59 · 1749 阅读 · 0 评论 -
图---邻接矩阵(建立,深度遍历,广度遍历)
图的存储方式可以用邻接矩阵来表示,我们假定顶点序号从0开始,即图G的顶点集的一般形式是V(G)={v0,vi,…,Vn-1}。以下代码测试过,为图的邻接矩阵表示方式。转载 2014-08-19 14:22:19 · 1796 阅读 · 0 评论 -
最小-最大搜索
从浅显的地方开始 在国际象棋里,双方棋手都知道每个棋子在哪里,他们轮流走并且可以走任何合理的着法。下棋的目的就是将死对方,或者避免被将死,或者有时争取和棋是最好的选择。 国际象棋程序通过使用“搜索”函数来寻找着法。搜索函数获得棋局信息,然后寻找对于程序一方来说最好的着法。 一个浅显的搜索函数用“树状搜索”(Tree-Searching)来实现。一个国际象棋棋局通常可以看作一转载 2014-08-29 09:51:05 · 2513 阅读 · 1 评论 -
简介(一)
什么样的结点需要搜索?全部还是选择性的?转载 2014-08-29 11:24:41 · 2053 阅读 · 0 评论 -
简介(二)
尽管我们已经讨论过Alpha-Beta搜索简单有效,还是有很多方法试图更有效地对博弈树进行搜索。它们中的大部分思想就是,如果认为介于Alpha和Beta间的评价是感兴趣的,而其他评价都是不感兴趣的,那么对不感兴趣的评价作截断会让Alpha-Beta更有效。如果我们把Alpha和Beta的间距缩小,那么感兴趣的评价会更少,截断会更多。 首先让我们回顾一下原始的Alpha-Beta搜索,忽略转载 2014-08-29 11:58:13 · 1736 阅读 · 0 评论 -
期望窗口
期望窗口是对迭代加深的改进。迭代加深的最简单的实现方法是这样的: for (depth = 1; ; depth ++) { val = AlphaBeta(depth, -INFINITY, INFINITY); if (TimedOut()) { break; }} 这里调用了一个“窗口”为正负无穷大的Alpha-Beta搜索,以假定返回值可能是很大的正数或负数。 假设下一次迭代时,搜转载 2014-08-29 12:18:49 · 1804 阅读 · 0 评论 -
简介(一)
搜索树 任何棋类游戏都要定义一棵有根的树(即“博弈树”),一个结点就代表棋类的一个局面,子结点就是这个局面走一步可以到达的一个局面。例如下图是井子棋(Tic-tac-toe)的搜索树: (实际上,这个搜索树的根结点应该有9个子结点,但是我去掉了一些对称的情况。如果同样的棋盘是由两个不同的着法顺序形成的,那么我们就建立两个结点,所以这的确是树的结转载 2014-08-29 09:55:10 · 1819 阅读 · 0 评论 -
十大编程算法
转载:http://www.techug.com/post/10-algorithm-help-programmer-grow-up.html算法一:快速排序算法快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更转载 2017-04-23 16:56:15 · 5471 阅读 · 0 评论 -
01 背包
01背包问题描述:给定 n 种物品和一背包,物品 i 的重量是 wi,其价值是 vi,背包容量为 c,问应如何选择装入背包中的物品,使装入背包中的物品价值最大?回溯法在搜索解空间树时,只要其左儿子节点是一个可行节点,搜索就进入其左子树。当右子树中可能包含最优解时才进入右子树搜索。设 r 是当前剩余物品的价值总和;cv 是当前价值;max 是当前最优价值。当 cv + r <= max 时, 可减去右原创 2016-05-19 18:52:40 · 1680 阅读 · 0 评论 -
B树、B+树、B*树
B树具体讲解之前,有一点,再次强调下:B-树,即为B树。因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解。如人们可能会以为B-树是一种树,而B树又是一种一种树。而事实上是,B-tree就是指的B树。特此说明。我们知道,B 树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支转载 2016-05-08 13:12:49 · 2404 阅读 · 0 评论 -
输入挂
输入挂,原理是把文件里面的东西用fread一次性读到内存。 使用时必须 #include “cctype”, 先调用 IO:init(); 然后全部用 IO:readint() 读入数据;namespace IO { const static int maxn = 200 << 20; static char buf[maxn], *pbuf = buf, *End;原创 2015-08-17 20:41:50 · 2060 阅读 · 0 评论 -
手动扩栈
方案一:(普通版)#pragma comment(linker, "/STACK:102400000,102400000")方案二:(汇编版)const int main_stack = 16;char my_stack[128<<20];int main() { __asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");原创 2015-08-17 20:49:44 · 2283 阅读 · 0 评论 -
Nim
Nim游戏的概述:还记得这个游戏吗? 给出n列珍珠,两人轮流取珍珠,每次在某一列中取至少1颗珍珠,但不能在两列中取。最后拿光珍珠的人输。 后来,在一份资料上看到,这种游戏称为“拈(Nim)”。据说,它源自中国,经由被贩卖到美洲的奴工们外传。辛苦的工人们,在工作闲暇之余,用石头玩游戏以排遣寂寞。后来流传到高级人士,则用便士(Pennies),在酒吧柜台上玩。 最有名的玩法,是把十二枚便士放成3、转载 2015-07-31 20:33:21 · 1669 阅读 · 0 评论 -
基于贪心算法的几类区间覆盖问题
(1)区间完全覆盖问题问题描述:给定一个长度为m的区间,再给出n条线段的起点和终点(注意这里是闭区间),求最少使用多少条线段可以将整个区间完全覆盖样例:区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]解题过程:1将每一个区间按照左端点递增顺序排列,拍完序后为[1,4],[2,4],[2,6],[3,5],[3,6],[3,7],[6,8]2转载 2015-08-10 10:22:48 · 2047 阅读 · 0 评论 -
Manacher算法--O(n)回文子串算法
O(n)回文子串算法注:转载的这篇文章,我发现下面那个源代码有点bug。。。在下一篇博客中改正了。。 这里,我介绍一下O(n)回文串处理的一种方法。Manacher算法.原文地址:http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-转载 2015-05-13 10:16:13 · 1662 阅读 · 0 评论 -
二叉树遍历(前序,中序,后序)
前序遍历(DLR) 前序遍历也叫做先根遍历,可记做根左右。 前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。 若二叉树为空则结束返回,否则: (1)访问根结点 (2)前序遍历左子树 (3)前序遍历右子树 注意的是:遍历左右子树时仍然采用前序遍历方法。中序遍历(LDR)转载 2014-08-05 10:29:45 · 1791 阅读 · 0 评论 -
优先队列用法
转载:http://www.cppblog.com/shyli/archive/2007/04/06/21366.html优先队列用法在优先队列中,优先级高的元素先出队列。标准库默认使用元素类型的优先队列的第一种用法,也是最常用的用法:priority_queueint> qi;通过故示例1中输出结果为:9 6 5 3 2第二种方法:在示例1中,如果我们转载 2015-04-07 19:37:33 · 1496 阅读 · 0 评论 -
图的遍历 (深搜DFS与广搜BFS)
图的遍历 图的遍历有两种遍历方式:深度优先遍历(depth-first search)和广度优先遍历(breadth-first search)。1.深度优先遍历 基本思想:首先从图中某个顶点v0出发,访问此顶点,然后依次从v0相邻的顶点出发深度优先遍历,直至图中所有与v0路径相通的顶点都被访问了;若此时尚有顶点未被访问,则从中选一个顶点作为起始点,重复上述过程,直到所有转载 2014-08-10 09:38:13 · 1736 阅读 · 0 评论 -
C++栈和队列
使用标准库的栈和队列时,先包含相关的头文件#include#include定义栈如下:stack stk;定义队列如下:queue q;栈提供了如下的操作转载 2014-08-19 14:43:54 · 3059 阅读 · 0 评论 -
二分图最大匹配
转载出处http://blog.youkuaiyun.com/dark_scope/article/details/8880547匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。-------等等,看得头大?那么请看下面的版本:转载 2014-11-26 22:38:01 · 1533 阅读 · 0 评论 -
stl算法:next_permutation剖析
在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组数据的全排列.但是怎么用,原理如何,我做了简单的剖析.首先查看stl中相关信息.函数原型:template bool next_permutation( BidirectionalIterator _First, BidirectionalIterato转载 2014-08-11 10:19:29 · 1517 阅读 · 0 评论 -
C style字符串
C style string(C风格字符串)的定义如下:C程序把指向以空字符结束的字符数组的指针视为字符串。在C++中,字符串字面值就是C风格字符串。C标准库定义一系列处理这种字符串的库函数,C++中将这些标准库函数放在cstring头文件中。由于C风格字符串本质上容易出错,C++程序应该优先使用C++标准库类string而少使用C风格字符串。C++标准库类string比C风格字符串更安全,效转载 2014-08-19 15:11:49 · 2766 阅读 · 0 评论 -
迭代加深
迭代加深 一个听起来不怎样的思想 如果你准备开始搜索一个国际象棋的局面了,你要搜索多深呢?事先预测搜索将进行多少时间,这有些困难,因为完成D层搜索所需要的时间取决于很多不确定的因素。在复杂的中局局面里,你可能不会搜索得很深,而在残局中你可能会搜索得非常深,在某些王兵残局里你可能会搜索100多层【译注:这也太夸张了点吧】。 有一个思想,就是一开始只搜索一层,如果搜索转载 2014-08-29 09:41:28 · 2431 阅读 · 0 评论 -
简介(二)
浅的裁剪 假设你用最小-最大搜索(前面讲到的)来搜索下面的树: 你搜索到F,发现子结点的评价分别是11、12、7和9,在这层是棋手甲走,我们希望他选择最好的值,即12。所以,F的最小-最大值是12。 现在你开始搜索G,并且第一个子结点就返回15。一旦如此,你就知道G的值至少是15,可能更高(如果另一个子结点比G更好)。这就意味着我们不指望棋手乙走G这步了,因为就转载 2014-08-29 09:59:39 · 1659 阅读 · 0 评论 -
空着裁剪
空着向前裁剪没有副作用即可获得额外的速度 空着向前裁剪(Null-Move Forward Pruning),运用可能忽视重要路线的冒险策略,使得国际象棋的分枝因子锐减,它导致搜索深度的显著提高,因为大多数情况下它明显降低了搜索的数量。它的工作原理是裁剪大量无用着法而只保留好的。 这个技术在很多刊物上报道过,但是使得大家都来关注空着的,则是由Chrilly Donniger发转载 2014-08-29 12:12:11 · 2730 阅读 · 0 评论 -
搜索的不稳定性
没有这个,生活会更有趣 当你试图写很强或很完美的程序时,搜索的不稳定性就可能出现。有很多原因可以导致不稳定性,当我讨论搜索的诸多改进方法时,顺便讨论了它们是如何导致搜索不稳定的。其他我没有讨论的搜索技巧也必须考虑不稳定的可能。 不稳定的搜索会返回无效的值,你用(5, 25)的Alpha-Beta窗口会高出边界,因此你用(24, INFINITY)重新搜索,却低出边界。这不应该发生,因为高出边转载 2014-08-29 12:25:04 · 1728 阅读 · 0 评论 -
STL set基本用法
set集合容器:实现了红黑树的平衡二叉检索树的数据结构,插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,以保证每个子树根节点键值大于左子树所有节点的键值,小于右子树所有节点的键值;另外,还得保证根节点左子树的高度与右子树高度相等。平衡二叉检索树使用中序遍历算法,检索效率高于vector、deque和list等容器,另外使用中序遍历可将键值按照从小到大遍历出来。构造set集合主要转载 2014-09-04 20:12:11 · 1660 阅读 · 0 评论 -
动态规划01背包问题
动态规划是用空间换时间的一种方法的抽象。其关键是发现子问题和记录其结果。然后利用这些结果减轻运算量。比如01背包问题。 因为背包最大容量M未知。所以,我们的程序要从1到M一个一个的试。比如,开始任选N件物品的一个。看对应M的背包,能不能放进去,如果能放进去,并且还有多的空间,则,多出来的空间里能放N-1物品中的最大价值。怎么能保证总选择是最大价值呢?看下表。测试数据:转载 2014-11-21 19:20:06 · 1802 阅读 · 0 评论 -
最长公共子序列(LCS)问题
程序员编程艺术第十一章:最长公共子序列(LCS)问题0、前言 程序员编程艺术系列重新开始创作了(前十章,请参考程序员编程艺术第一~十章集锦与总结)。回顾之前的前十章,有些代码是值得商榷的,因当时的代码只顾阐述算法的原理或思想,所以,很多的与代码规范相关的问题都未能做到完美。日后,会着力修缮之。 搜遍网上,讲解这个LCS问题的文章不计其数,但大多给读者一种并不友好的感觉,稍感转载 2014-11-14 16:37:07 · 2051 阅读 · 0 评论 -
六类qsort排序方法
前一段时间做题觉得qsort函数很好用,但有时不太会用比如按结构体一级排序、二级排序、字符串排序等,故通过查资料将其整理一番。以下是其具体分类及用法(若无具体说明是以降序排列):1、对一维数组排序:(Element_type是一位数组中存放的数据类型,可以是char, int, float, double, etc )int Comp(const void *p1,const vo转载 2014-07-12 10:05:45 · 1591 阅读 · 0 评论 -
C++标准库string类型
string类型支持长度可变的字符串,C++标准库将负责管理与存储与字符串相关的类容,以及提供各种有用的操作。标准库string类型的目的就是满足对字符串的一般应用。包含头文件转载 2014-08-19 14:57:53 · 1670 阅读 · 0 评论 -
Alpha-Beta搜索
《对弈程序基本技术》专题 Alpha-Beta搜索 Bruce Moreland / 文 最小-最大的问题 Alpha-Beta 同“最小-最大”非常相似,事实上只多了一条额外的语句。最小最大运行时要检查整个博弈树,然后尽可能选择最好的线路。这是非常好理解的,但效率非常低。每次搜索更深一层时,树的大小就呈指数式增长。 通常一个国际象棋局面都有35个左右的合转载 2014-08-29 09:43:50 · 1731 阅读 · 0 评论 -
简介(三)
我还没有讲完Alpha-Beta呢,因为我的伪代码里包含神秘的“排序着法”还没有解释,暂时先扔在一边,在讲完散列技术后,我将继续这部分内容。 散列技术的思想非常简单,很多棋类会出现“置换”的着法,即着法顺序的不同会导致相同的局面。例如在国际象棋中,开局走“1. d4 Nf6 2. c4”和“1. c4 Nf6 2. d4”都会导致一样的局面(称为印度防御),白方两次进兵可以按不同的顺序走。再看一转载 2014-08-29 10:02:13 · 1692 阅读 · 0 评论 -
STL priority_queue
priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数,priority_queueType 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.STL里面容器默认用的是 vector. 比较方式默认用 operator转载 2014-10-12 15:11:01 · 1519 阅读 · 0 评论 -
最短路径—Dijkstra算法
Dijkstra算法 (转载:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html)1.定义概览Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很转载 2014-12-04 21:18:01 · 1870 阅读 · 0 评论