随笔分类 -  算法导论

摘要:《算法导论》学习记录目录这一章是对第十三章红黑树的扩张(PS:关于红黑树的介绍见链接)。在现实应用中我们经常需要在一些数据结构(链表、二叉树)上添加一些特性来解决问题。以前看书的时候从没有认真看过这一章,老是觉得没什么用。这次认真的看完、思考后,觉得真心不错。之前老是对扩张数据结构没什么概念,在解决某些问题的时候没有考虑使用某些算法或者数据结构的扩张去解决问题。第一是自己对算法和数据结构的认识还不够深入;第二是没有结合问题的特性和某些算法或者数据结构的特性来解决问题。以后要多加注意。顺序统计树顺序统计树是在红黑树的上添加一个size特性,每个结点都含有size域,size域的值为以该点为根的子 阅读全文
posted @ 2014-04-10 17:53 alan_forever 阅读(2128) 评论(0) 推荐(1) 编辑
摘要:《算法导论》学习记录目录红黑树是"平衡的"二叉查找树(PS: 关于二叉查找树的内容见链接)。普通的二叉查找树,在最坏情况下基本操作的运行时间为Θ(n),大部分的操作的最坏情况运行时间与树的高度成正比,对于相同的数据如何构造出一棵高效的二叉查找树(即高度尽量小)(如下图)图a为高效的二叉查找树,图b为低效的二叉查找树造成图b中的二叉查找树低效的原因在于建树的时候结点插入的顺序不恰当,选取关键字为2的结点(最小关键字结点)作为根结点使得所有的结点都位于根结点的右子树里。更糟糕是所有的结点都在同一条路上,这时候就相当于在链表上进行操作。但是普通的二叉查找树不会自动调整,使自己的尽 阅读全文
posted @ 2013-11-23 00:54 alan_forever 阅读(2618) 评论(0) 推荐(3) 编辑
摘要:《算法导论》学习记录目录查找树是一种支持包括查找、插入、找最小值、找出最大值、找出前趋、找出后继、删除动态集合操作的数据结构。基本操作的时间与树的高度成正比,对于一棵含有n个结点的完全二叉树,基本操作的最坏情况运行时间为Θ(lgn),对于含有n个结点的树(不是完全二叉树),最坏的情况(线性链)运行时间为Θ(n)。二叉查找树的性质:x为二叉查找树的一个结点,x_l 为x的左子树中的一个结点,那么x_l存储的关键字小于或者等于x存储的关键字;x_r为x的右子树中的一个结点,那么x_r存储的关键字大于或者等于x存储的关键字。如下图所示:二叉树可以用链表结构来表示,每个结点除了关键字和卫星数据外,还有 阅读全文
posted @ 2013-11-07 22:58 alan_forever 阅读(1842) 评论(2) 推荐(5) 编辑
摘要:《算法导论》学习记录目录散列表(哈希表)是根据关键字直接访问内存存储位置的数据结构,仅支持插入、查找、删除操作。在最坏情况下,查找一个元素的时间为Θ(n),而在一些合理的假设下,查找一个元素的期望时间为O(1)。散列表是普通数组的推广。对于普通数组: 1、我们可以将关键字为k的元素存到数组下标为k的位置里。 2、如果有一个关键字k,我们直接查看数组下标为k的位置。这种方式为直接寻址方式。但是这种方式有不足:只适用于关键字的全域比较小,而且没有两个元素的关键字完全相同。而显示中存储的关键字集合会比关键字的全域相对小很多。下图为直接寻址表:代码实现如下:(刚开始打算直接开个装元素的数组... 阅读全文
posted @ 2013-10-27 20:49 alan_forever 阅读(5251) 评论(3) 推荐(2) 编辑
摘要:《算法导论》学习记录目录基本的数据结构是很基础的东西,而且运行时间也很容易看出来,所以本文也是简单地提及一些性质,主要还是通过一些练习来熟悉它们的性质。(PS:无聊翻开TAOCP的第一卷,发现第二章也是讲一些数据结构,而且讲得很详细。如果明年年初计划可以完成,就应该开始看TAOCP,继续努力吧!)栈栈是先进后出(后进先出),就好像洗盘子的时候,你最先放的盘子在最底,下次拿出来洗,就是最后才拿出来。(例子举得有点搓。。。)具体操作为进栈、出栈(也叫压入、弹出)。因为是基于数组来实现栈,所以不仅仅要注意下溢(空栈出栈),还要注意上溢(满栈进栈)。 1 #include 2 #include 3.. 阅读全文
posted @ 2013-10-20 11:49 alan_forever 阅读(2571) 评论(4) 推荐(0) 编辑
摘要:《算法导论》学习记录目录本章主要讲了如何在一个集合里找出第i个顺序统计量(即第i个小的元素),可以定义选择问题(n个元素中的第i个小的元素,即在n个元素里找出一个元素,这个元素大于其他i-1个元素)。如果我们用堆排序或合并排序(Ο(nlgn))对该集合进行排序,然后直接找出第i个元素即可。这样一来,选择问题运行时间为Ο(nlgn)。但是本章讲其他两种方法可以使的选择问题的运行时间为O(n),分别为以期望线性时间做选择和最坏情况线性时间的选择。(PS:本人能力不足,对于最坏情况线性时间的选择的算法还在看,不能将其实现。。。。所以下文不会出现。。。)最小值最大值最小值和最大值都可以通过n-1次比较 阅读全文
posted @ 2013-10-11 22:03 alan_forever 阅读(1953) 评论(2) 推荐(0) 编辑
摘要:大一下学期买了《算法导论》打算玩ACM的时候学,后来ACM玩得不伦不类,算导也看得不伦不类,只看算法实现,忽略了很多东西。现在(大三),觉得之前大一大二都浪费了很多时间,也渐渐发现之前忽略很多基础。不知道为什么想把算法导论认真看一遍,把练习、思考题也做一做、看一看。顺便巩固一下C的编程能力,还有提高一下自己的表达能力。毕竟就算已经大三了,也还是要好好学习,不停地学习才是真正的生活。该文章为本人学习《算法导论》的记录的目录,所有关于《算导》的文章都会在下文的链接里。(本人能力有限,如有错误,欢迎指出。)第二章 插入排序(3种代码实现) 习题第六章 堆排序(代码实现) 习题与... 阅读全文
posted @ 2013-10-10 13:56 alan_forever 阅读(4241) 评论(3) 推荐(2) 编辑
摘要:《算法导论》学习记录目录比较排序:各个元素的次序基于输入元素间的比较。下界为Ω(nlgn)。线性排序:用非比较的操作来确定元素的顺序。决策树比较排序可以抽象地视为决策树,表示某排序算法对输入元素的所有比较。下图为插入排序对于三个元素的输入序列上的决策树:对于n个元素,排序结果有n!种排列,对应与决策树上的每一个叶子。一个正确的排序算法必须可以产生每一种排列,对于决策树来说就是从根结点出发可以到达每一个叶结点。在决策树中,从根到任一个叶结点之间最长路径的长度表示对应的排序算法中最坏情况下的比较次数。因此,一个比较排序的最坏情况比较次数与其决策树的高度相等。所以可得任意一个比较排序在最坏情况下,都 阅读全文
posted @ 2013-10-02 23:30 alan_forever 阅读(2297) 评论(0) 推荐(0) 编辑
摘要:《算法导论》学习记录目录快速排序,对于n个数的输入数组,最坏情况运行时间:Θ(n^2);期望运行时间:Θ(nlgn);就地排序(Sort in place)。数组A[p..r]会被分为两个子数组A[p..q-1]和A[q+1..r],其中A[p..q-1]的元素都不大于A[q],A[q+1..r]都... 阅读全文
posted @ 2013-09-28 18:21 alan_forever 阅读(4354) 评论(14) 推荐(2) 编辑
摘要:算导本章的优先级队列是堆数据结构的一个应用,优先级队列分为两种:最大优先级队列和最小优先级队列。主要内容是基于最大堆实现最大优先级队列。关于堆数据结构的内容见此:堆。下文有关堆的代码解释也在链接的文章。“优先级队列是一种用来维护由一种元素构成的集合S的数据结构,这一组元素中的每一个都有一个关键字key。“------《算法导论》我的代码实现与算导中关于最大优先级队列的支持操作有出入,我将increase-key操作删除,把insert操作修改了一下。具体支持的操作为下:1 int heap_maximum(int A[]); //返回优先队列的最大值2 3 i... 阅读全文
posted @ 2013-09-22 19:52 alan_forever 阅读(2257) 评论(0) 推荐(2) 编辑
摘要:《算法导论》学习记录目录欢迎指出其中的错误和交流。关于堆排序的具体介绍和C代码实现见该链接。算导关于堆排序的练习主要是一些证明,可以帮助理解堆的特征。部分练习是图示过程,这些练习认真用笔过一次会很有收获。1.在高度为h的堆中,最多和最少的元素个数是多少?最多:底层全满;1 + 2^1 + 2^2 + ...... + 2^h,等比数列求和得2^(h+1) - 1最少:底层只有一个节点;1 + 2^1 + 2^2 + ...... + 2^(h-1) + 1,等比数列求和得2^h - 1 + 1 = 2^h2.证明:含n个元素的堆的高度为floor(lgn)假设n个元素的堆的高度为h。由上题得2 阅读全文
posted @ 2013-09-16 20:47 alan_forever 阅读(7247) 评论(2) 推荐(1) 编辑
摘要:《算法导论》学习记录目录堆数据结构是一种数组对象,它可以被视为一棵完全二叉树。二叉堆有两种:最大堆和最小堆。最大堆的特性是指除了根以外每个节点的值最多和其父节点的值一样大。堆可以被看成是一棵树,其高度为。(练习证明)保持堆的性质 1 /* 2 *这个函数是维持堆的性质,注意当调用这个函数的时候,我们假定该节点的左右儿子树都是最大堆。 3 *但是有可能该节点小于它的子树,所以通过这个函数使该节点下降,使以该节点为根的子树成为最大堆。 4 */ 5 void max_heapify(int A[], int length, int i){ 6 int l = 2 * i; ... 阅读全文
posted @ 2013-09-13 23:26 alan_forever 阅读(2596) 评论(2) 推荐(0) 编辑
摘要:《算法导论》学习记录目录1、写出一个运行时间为的算法,使之能在给定一个由n个整数构成的集合S和另一个整数时,判断出S中是否存在有两个其和等于x的元素。首先对集合进行排序,用归并排序(),然后再从集合的第一个元素到最后一个元素,对集合进行二分查找,查找x减去该元素() 1 #include 2 #include 3 4 void merge(int A[], int p, int q, int r){ 5 int n1 = q - p + 1; 6 int n2 = r - q; 7 int i, j, k; 8 int *L = mallo... 阅读全文
posted @ 2013-09-02 18:14 alan_forever 阅读(1233) 评论(0) 推荐(0) 编辑
摘要:《算法导论》学习记录目录插入排序是算导第一个分析的算法。之前看了很多遍,一直没有把习题做了,现在好好把习题和思考题做做,锻炼自己能力,顺便用C语言实现经典算法和数据结构。最基础的插入排序是对前n-1项数据进行反向扫描。实现很简单,运行时间也很容易的出,直接贴代码:void insertion_sort(int A[], int length){ int i, j; int key; for(j = 1; j = 0 && A[i] > key) { A[i+1] = A[i]; i--; } ... 阅读全文
posted @ 2013-09-01 14:43 alan_forever 阅读(7531) 评论(0) 推荐(0) 编辑