![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构
文章平均质量分 69
AscendingOne
这个作者很懒,什么都没留下…
展开
-
【整理】数据结构——题目
文章目录前言一、预备知识a. 了解C++和Java基本语法结构,掌握递归思想。二、程序性能a. 了解复杂性表示和计算方法b. 掌握插入排序、选择排序、冒泡排序、名次排序的基本思想三、数据描述a. 掌握线性表的公式化描述、链表描述、间接寻址等存储方法b. 了解遍历器的作用和实现方法c. 掌握线性表的插入、删除、合并等运算方法d. 掌握箱子排序,计数排序前言已经到冲刺阶段了,整理尽量缩短时间。按100道非重复的题目来算,一天整理十道,最多需要30天整理完成,因为给专业课的时间现在还不是很多,废话不多说,开始原创 2020-11-06 09:32:47 · 2453 阅读 · 7 评论 -
动态规划及动态规划的应用
前言相比于其他算法思想,动态规划的难度较大。同时,动态规划也是最强力的一种算法思想。有很多问题,用贪婪思想或者分而治之无法简洁而高效的解决,但是用动态规划就可以。动态规划的基础为最优原理。...原创 2020-08-18 20:01:00 · 1202 阅读 · 0 评论 -
分而治之—归并排序与快速排序
文章目录前言分而治之思想归并排序1)算法思想2)C++实现3)复杂度分析时间复杂度空间复杂度前言对于贪婪算法的学习暂时告一段落,我们开始学习下一个算法设计思想——分而治之。这一部分涉及的应用同样也很广泛,我们选取归并排序和快速排序进行分析。分而治之思想什么是分而治之思想?利用分而治之思想解决问题一般分为三个步骤:将问题分成多个类型相同的子问题。按照问题设计算法解决子问题,且子问题的求解策略与原问题十分相似。把各个子问题的解答组合起来,即可得到原问题的解答。因为要分解为很多子问题,我们可原创 2020-08-14 17:58:13 · 396 阅读 · 0 评论 -
贪婪算法 — 最小生成树Kruskal和Prim算法
前言在讨论图的时候,我们利用DFS和BFS搜索构成过生成树。但是在加权无向图中,由DFS或BFS生成的生成树一般不具有最小成本(即生成树的边集之和)。但是现实生活中又有最小生成树的应用,比如在一个城市中的送水站或快递公司应该建在哪里的问题。我们优秀的前辈们开始设计算法来解决这个实际问题。这次要介绍的Kruskal和Prim同样也是以作者名字命名的算法。这两个算法的逻辑都很简单,关键点是要明白为什么这两个算法是可行的,也就是要验证算法的正确性。同时,还要注意数据结构的选取。Kruskal算法1)问题原创 2020-08-12 15:04:50 · 797 阅读 · 0 评论 -
贪婪算法—单源最短路径Dijkstra算法
文章目录前言贪婪算法单源最短路径Dijkstra算法1)关于作者2)问题描述3)算法思想4)数据结构的选择5)伪代码6) 验证算法正确性7)算法的复杂度前言本节的部分内容来自《算法导论》,因为《数据结构、算法和应用》这本书在算法设计部分注重于与前面所写的类的联系和实现。优点是贴近实际应用,但是在讲述单纯算法时,超级长的变量命名和注释却掩盖了算法最纯粹的思想。算法和应用当然同等重要,但是要对算法有充分的理解才有应用的可能。贪婪算法单源最短路径Dijkstra算法1)关于作者以往我也尝试过寻找数原创 2020-08-08 21:14:23 · 2048 阅读 · 0 评论 -
贪婪算法—拓扑排序
文章目录前言贪婪算法贪婪算法的应用1)AOV网的拓扑排序算法前言这一部分,数据结构已经不再重要了,开始进入到了算法设计的领域。在《数据结构、算法与应用》一书中,描述了一部分重要的算法设计方法,包括贪婪算法、分治算法、动态规划、回溯和分支定界。并且对于算法的讨论不如《算法导论》中细致周密。数据结构专栏暂时只关注贪婪、分治和动规三种算法设计方法。贪婪算法贪婪算法的算法设计思想,每一步,我们都在一定的标准下,作出一个最优决策。在每一步做出的决策,在以后的步骤中都不可更改。做出决策所依据的标准称为贪婪准则。原创 2020-08-08 12:03:14 · 657 阅读 · 0 评论 -
数据结构(二十一)——图和图的应用
文章目录前言图(graph)1)图的基本概念及特性2)图的描述3)图的类实现4)图的遍历5)图的应用前言本章是数据结构逻辑的最后一种形式,图状结构。因为本章只讲述了图结构的冰山一角,所以结构非常清晰。图(graph)图是最复杂的一种数据结构,也是最能表述现实应用的数据结构。人际关系、航线、网络中的节点等等许多接近实际的问题都可以用图来描述。1)图的基本概念及特性图:在数据结构领域,我们把图抽象为有限集V和E的有序对,即用边连接在一起的顶点的集合。就像望月新一证明ABC猜想一样,要学习图,首先要原创 2020-08-04 12:11:28 · 1184 阅读 · 0 评论 -
数据结构(二十)——m叉搜索树和B树
文章目录前言(一)m叉搜索树1)什么是m叉搜索树?2)节点个数与高度3)搜索4)插入5)删除(二)B树1)什么是B树?2)为什么是B树?3)节点个数与高度4)搜索5)插入6)删除(三)B+树什么是B+树?前言以前的数据结构中,我们默认数据都存放在同一存储介质中,比如内存。但在实际应用中,大型字典因为数据量过大一般存储在磁盘中,等到用的时候再从磁盘取出利用内存处理。在磁盘中存取数据的速度比在内存中处理大概慢几十倍甚至百倍。所以对于存储在磁盘中的数据,存取所需要的数据需要访问磁盘的次数就变成了非常重要的指原创 2020-07-31 14:42:05 · 4746 阅读 · 4 评论 -
数据结构(十九)——AVL搜索树及插入、删除操作详细图解
文章目录前言AVL树与AVL搜索树AVL搜索树各操作AVL搜索树的搜索(find)AVL搜索树的插入(insert)AVL搜索树的删除(erase)前言接着上一节的二叉搜索树,我们今天分析平衡搜索树的一种——AVL搜索树。在《数据结构、应用与算法》这本书中和课程PPT上都没有找到AVL搜索树的代码实现。在书的课程网站上也没找到相应代码。加上复习节奏紧凑,本篇文章暂时不涉及代码,专注于插入和删除操作的逻辑和伪代码,请谅解。AVL树与AVL搜索树为什么要学习AVL搜索树?请见这里的二叉搜索树部分。A原创 2020-07-26 15:06:26 · 1926 阅读 · 0 评论 -
数据结构(十八)——二叉搜索树及实现
文章目录前言二叉搜索树为什么使用二叉搜索树?二叉搜索树实现类搜索插入删除前言从二叉搜索树开始,到下一节的AVL树以及下下节的B树,都适合于字典描述。以前和字典相关的数据结构是线性结构跳表和散列,这一章到了树形结构。二叉树的删除方法要特别注意,涉及到四个指针在树上游荡,需要理清每步的逻辑关系。二叉搜索树为什么使用二叉搜索树?和其它每种数据结构一样,都有其存在的意义,优势及劣势。二叉搜索树也要与同为字典描述的跳表和散列进行对比。查找(平均、最坏)插入删除跳表Θ(logn)原创 2020-07-22 11:20:53 · 250 阅读 · 0 评论 -
数据结构(十七)——霍夫曼编码与霍夫曼树
文章目录前言霍夫曼编码思想定长与变长WEP霍夫曼树构建霍夫曼树为什么霍夫曼树WEP最小实现时间复杂度前言本节中的霍夫曼树可以看作最小堆的应用。霍夫曼编码则是霍夫曼(Huffman)设计的一种压缩算法。霍夫曼编码是思想,霍夫曼树是实现。霍夫曼编码思想定长与变长WEP霍夫曼树构建霍夫曼树为什么霍夫曼树WEP最小实现时间复杂度...原创 2020-07-20 09:29:05 · 810 阅读 · 1 评论 -
数据结构(十六)——左高树(含合并过程详细图解)
文章目录前言左高树什么是左高树?为什么要使用左高树?最大左高树实现及复杂度分析节点类和最大左高树类合并方法插入(push)、删除(pop)初始化左高树合并图解前言看到左高树的时候,对左高树的印象大概只有左高树这三个字了。看的时候费劲了一点,因为不知道这个数据结构是干嘛的。网上的资料也比较少。所以这篇文章理解能力有限,请见谅。左高树什么是左高树?左高树大致分为高度优先左高树和重量优先左高树两类。本文以高度优先左高树为例。左高树中定义了几个新的概念,比如外部节点、内部节点和扩充二叉树。外部节点原创 2020-07-18 11:18:00 · 2314 阅读 · 3 评论 -
数据结构(十五)——堆与堆排序及时间复杂度分析
文章目录前言堆(Heap)堆是什么为什么要使用堆堆的实现及时间复杂度分析堆的类声明堆的插入方法堆的删除方法初始化堆堆排序前言上一篇数据结构文章分析了二叉树的实现及其遍历方法,学习了树形结构。但当时我没有思考为什么要学习树形结构这个问题。这篇堆和堆排序是二叉树的应用分析,回答了这个问题。堆(Heap)堆是什么堆是一颗有最大堆和最小堆之分 / 在最大堆中每个节点的值都大于等于其子节点(如果有子节点的话)的值 / 最小堆定义类似 / 的完全二叉树。堆的基本操作包括初始化堆,插入堆,获取堆元素,删除堆。原创 2020-07-16 15:54:55 · 12767 阅读 · 0 评论 -
数据结构(十四)——二叉树遍历相关练习
练习题来自王道,部分题目与参考答案中的思路不同。这些题主要是考察二叉树三种递归的遍历方法,三种非递归的遍历方法,以及层次遍历。如有错误,欢迎指正!/*编写后序遍历二叉树的非递归算法算法思想:提供一标签指针,在访问右孩子时判定,若已访问过输出节点时间复杂度:O(n) 空间复杂度:O(n)*/void postOrder(BinaryTreeNode* t){ Stack s; BinaryTreeNode* p = t; BinaryTreeNode* pre;原创 2020-07-13 21:35:28 · 1124 阅读 · 0 评论 -
数据结构(十三)——二叉树与函数指针
碎碎念(可以直接跳过):这大概是数据结构中我写过的最复杂的类定义,看《数据结构应用与算法》到二叉树这里时,一直疑惑函数指针是干什么的,为什么类中要用到函数指针,为什么同一遍历方法要写两遍,一遍私有一遍公有,私有的函数方法为什么要定义成静态函数。二叉树这里一半时间都在研究这个了,因为书上的参考代码肯定是优美、通用且精简,我不理解很正常,当初上课时也没有好好想这个问题。我对比了书上的代码和课程PPT上的代码,找了函数指针和一些资料,大概明白了为什么这样写。首先看函数指针:函数指针:意义为指向函数的指针,通过原创 2020-07-13 17:51:49 · 998 阅读 · 0 评论 -
数据结构(十二)——浅谈并查集
前言这里没有路径压缩+按秩合并时证明反Ackermann函数的时间复杂度的内容,如有兴趣请查看《算法导论》第21章。本文重点强调对并查集的理解,以及各种优化算法的实现。除上面的优化算法外都会给出时间复杂度证明。并查集什么是并查集,解决的是什么问题?并查集问题又叫做在线等价类问题,涉及将n个不同的元素分为一组不相交的集合。这些集合涉及三个操作,初始化(initialize),寻找(find)和合并(union)。初始化:每个元素独自构成一个集合,如果有n个元素,则有n个集合。寻找:查找元素所在原创 2020-07-06 21:47:32 · 637 阅读 · 0 评论 -
数据结构(十一)——散列和字典小结
文章目录前言字典字典是如何和散列与跳表联系起来的呢?散列散列函数p这样选取的原因冲突与溢出处理冲突的方法散列性能分析散列实现前言看完散列和跳表的部分,最大的感受的就是已经开始摆脱基本的数据结构,比如栈和队列,代码的实现开始复杂起来。这一部分引出了一个新的概念 —— 字典。字典字典: 字典由一些形如(k,v)的数对所组成的集合,其中k是关键字(key),v是与关键字k对应的值(value)。比如学号和你的一门成绩对应,key便是你的学号,value便是你的成绩。字典是如何和散列与跳表联系起来的呢?原创 2020-07-02 23:01:53 · 615 阅读 · 0 评论 -
数据结构(十)——队列(queue)小结
逻辑结构:线性结构存储结构:数组描述或链表描述对数据的运算:empty()、size()、pop()、push(x)、front()、back()概念:生活中的排队,讲究“先来后到”。应用实例:列车车厢重排等等队列实现有两个特别需要注意的点:数组实现时由公式化实现的环状空间(逻辑上的环状,物理上仍是一维数组)数组实现时判断栈队列满和队列空逻辑上的环状空间:优势 :重复利用出队列的元素的空间具体表现:队列弹出元素时,头指针:Q.front = (Q.front+1)%max原创 2020-06-28 22:24:04 · 335 阅读 · 0 评论 -
数据结构(九)—— 栈(Stack)小结
栈:可能是应用频率最高的数据结构之一(另外一个是队列),是线性表的限制版。把线性表的插入和删除操作限制在同一端进行,就得到栈数据结构。由于是线性表的限制版,栈的所有操作在线性表上都可以进行,那为什么还要专门设计栈这一种数据结构呢我的理解是公式化描述和链式描述已经从最根本上定义了线性表,栈可以直接从线性表类派生出,但会牺牲一些执行效率。栈的存在是线性表的应用的需要,为不同的需求制订出最匹配的解决方案,永远也用不到的一些部分则不需要为用户提供,即“奥卡姆剃刀原理”。所以栈以及马上要来的队列这一部分,都有两原创 2020-06-27 16:26:17 · 312 阅读 · 0 评论 -
数据结构(八)——数组与矩阵小结
章节标题虽然是数组与矩阵,但重点完全偏向于矩阵的存储结构。有关数组的部分也都是为存储矩阵做基础铺垫。另外,与以前章节更注重时间复杂度不同,本章更注重存储矩阵所占空间的优化。 所以之后对比的时候会加入对空间的利用效率。矩阵的存储结构分为四种:数组的数组(最普遍的做法)一维数组(重点部分,包括一般矩阵的存储和特殊矩阵的压缩存储)单个线性表(侧重于稀疏矩阵)多个线性表(侧重于稀疏矩阵)本文中的矩阵均默认为二维矩阵,m = 矩阵行数, n = 矩阵列数。数组的数组:所占空间: m * n *原创 2020-06-25 19:18:54 · 474 阅读 · 0 评论 -
数据结构(七)——链表描述线性表练习
/* 线性表的链式表示,王道综合应用题*//*结构体声明typedef struct LNode{ ElemType data; struct LNode *next;}LNode, *LinkList;*/// 1. 设计一个递归算法,删除不带头结点的单链表L中的所有值为x的结点// 算法思想:传递的为上一结点的指针域,挺有意思的一个算法// 时间复杂度:O(n),空间复杂度O(n)void deleteAllx(LinkList &L, El原创 2020-06-21 20:10:12 · 501 阅读 · 0 评论 -
数据结构(六)——间接寻址
其实在作为链表成员函数的箱子排序中已经用到间接寻址,即指向指针的指针。chianNode<T> **bottom, **topbottom = new chainNode<T>* [range+1];top = new chainNode<T>* [range+1];这里的bottom保存的数据类型为chainNode* 的指针类型,指向指针的bottom便实现了间接寻址。因为书上没有用间接寻址实现线性表的代码,但是考试大纲上有提到。博主便参考多个案例加上自己原创 2020-06-14 17:47:25 · 1269 阅读 · 0 评论 -
数据结构(五)——线性表的链式描述小结
链式描述的线性表(使用指针)在占用内存、插入、删除、存取等方面都不如公式化线性表。那么它的优势在哪里呢?平衡二叉树结构,比如AVL和红黑树,使用基于指针的描述在最坏情况下的插入和删除要优于数组描述。链式描述的合并时间复杂度为O(1),在知道前驱的情况下,插入和删除操作的时间复杂度为O(1)有广泛的应用实例,指针更灵活,不受空间连续性的限制。很多很多…链式描述的线性表的插入、删除操作中内含的思想:为了保存firstNode,需要新建节点指针类型,即新建一个指针,复制firstNode的地址,原创 2020-06-13 22:29:16 · 239 阅读 · 0 评论 -
数据结构(四)——线性表的公式化描述小结
本文为公式化描述的抽象小记,不涉及基础知识。公式化线性表的核心操作:插入、删除、合并和搜索解题时可能用到的技巧:元素逆置、二分搜索、int类型模拟指针时间空间复杂度要求:时间复杂度O(n),空间复杂度大部分为O(1),最差为O(n)。时间复杂度为logn的题目较少,且最优解需要耗费时间。练习(仅供参考,部分题目非最优解)//从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值,空出的位置//由最后一个元素填补,若顺序表为空则显示出错信息并退出运行ElemType delete原创 2020-06-11 20:22:27 · 768 阅读 · 0 评论 -
数据结构(三)——C++ ostream与operator
本文主要介绍操作符与输入输出符的重载相关问题operator与操作符operator是操作符重载关键字,和public、const同一地位。主要重载“+”、“-”、“++”等操作符使用格式为operator直接连接要重载的操作符,函数在类内实现,代码逻辑清晰直观class Box{public: Box(int da){data = da;} Box operator+(const Box& b) { Box c(0); c.da原创 2020-06-07 22:31:45 · 3918 阅读 · 0 评论 -
数据结构(二)——C++中的*&
关于C++中*和&的用法及意义这里不再赘述,在各大网站和论坛中有详细且明确的解释。本文关注 *&,即 *与&同时使用的情况,以及为什么 *&可以实现改变指针。首先看一段代码:int main(){ int a = 1; int *b = &a; cout << "a value: " << a << endl; cout << "&a value: " << &原创 2020-06-05 10:34:02 · 1667 阅读 · 1 评论 -
数据结构(一)——C++基础
作为数据结构C++语言描述的草稿笔记,目的是通过书上的代码理解C++的编写逻辑。1. 函数返回数组问题 C++不允许函数返回一个数组,而是可以返回数组类型的指针。大概是返回数组需要占用太多的性能和空间。比如任意一个排序,传入函数的参数为数组的指针,在函数体内为数组排好序,返回数组指针。整个过程流畅而简洁。Java可以直接传入数组参数和返回数组,但其内部逻辑仍然是传入数组的地址和返回数组的地址,在函数内部期间并没有任何数组的复制发生。这使得Java更符合编程人员的逻辑,隐藏了运行的内部逻辑。2.数组初原创 2020-06-04 14:36:29 · 200 阅读 · 0 评论