
数据结构与算法
文章平均质量分 78
《数据结构与算法》书籍笔记
其木王·王子
Whatever,Smile to life!
不管怎样,笑着生活
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
24-经典排序算法之 冒泡排序
冒泡1. 冒泡排序(Bubble Sort)2. 代码实现3.算法分析总结1. 冒泡排序(Bubble Sort)冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。(如果是从小到大排序,总会将最大的值送到序列的末尾。)我用一个例子,带你看下冒泡排序的整个过程。我们要对一组数据 4,5,6,3,2,1,从小到大进行排序。第一次冒泡操作的详细过原创 2022-04-21 22:00:32 · 2912 阅读 · 2 评论 -
01-复杂度分析
复杂度分析复杂度也叫渐进复杂度,包括时间复杂度和空间复杂度,用来分析算法执行效率与数据规模之间的增长关系,可以粗略地表示,越高阶复杂度的算法,执行效率越低。1.大0表示法所有代码的执行时间 T(n) 与每行代码的执行次数 f(n) 成正比。我们可以把这个规律总结成一个公式。具体解释一下这个公式。其中,T(n) 我们已经讲过了,它表示代码执行的时间;n 表示数据规模的大小;f(n) 表示每行代码执行的次数总和。因为这是一个公式,所以用 f(n) 来表示。公式中的 O,表示代码的执行时间 T(n) 与原创 2021-10-24 22:55:42 · 233 阅读 · 0 评论 -
02-链表结构(Linked list)
链表1.五花八门的链表结构1.1 底层的存储结构1.2 三种最常见的链表结构1.2.1 单链表1.2.1 单链表的查找、插入、删除1.2.2 循环链表1.2.3 双向链表1.2.3.1 双向链表删除操作1.2.4 双向循环链表2. 链表 VS 数组性能大比拼3. 如何基于链表实现 LRU 缓存淘汰算法?1.五花八门的链表结构相比数组,链表是一种稍微复杂一点的数据结构。这两个非常基础、非常常用的数据结构,我们常常会放到一块儿来比较。所以我们先来看,这两者有什么区别。1.1 底层的存储结构我们先从底层的原创 2022-03-09 20:10:24 · 3716 阅读 · 1 评论 -
03-链表的基本操作
常见的链表操作1.几个写链表代码技巧1.几个写链表代码技巧1)理解指针或引用的含义我们知道,有些语言有“指针”的概念,比如 C 语言;有些语言没有指针,取而代之的是“引用”,比如 Java、Python。不管是“指针”还是“引用”,实际上,它们的意思都是一样的,都是存储所指对象的内存地址。实际上,对于指针的理解,只需要记住下面这句话就可以了:将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。在编写链原创 2022-03-15 20:09:41 · 187 阅读 · 0 评论 -
04-常见的链表操作 之 单链表反转
单链表反转1. 几个常见的链表操作2.单链表反转1. 几个常见的链表操作需要把这几个操作都能写熟练,不熟就多写几遍,我保证你之后再也不会害怕写链表代码。单链表反转链表中环的检测两个有序的链表合并删除链表倒数第 n 个结点求链表的中间结点2.单链表反转题目描述反转一个单链表。示例输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL思路分析1)根据题目给出的输入示例,构造出下的链原创 2022-03-15 20:12:28 · 1565 阅读 · 0 评论 -
05-常见的链表操作 之 判断链表是否有环
判断链表是否有环1. 判断链表是否有环2. 如果有环,如何找到这个环的入口题意:给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。主要考察两知识点:- 判断链表是否环- 如果有环,如何找到这个环的入口1. 判断链表是否有环思路要判断列表中是否有环,可以定义一个慢指针slow指向链表的头结点,快指针fast指向头结点的下一个结点。然后,慢指针slow每次向前移动一个位置,快指针fast每次向前移动两个位置。这样,如果链表中存在环,快指针就会先进入环,然后追上慢指针。原创 2022-03-17 23:02:15 · 1089 阅读 · 0 评论 -
06-链表的基本操作(插入与删除)
插入与删除_C语言实现1.利用哨兵简化实现难度2.链表中插入结点3. 链表中删除节点4. 完整实现1.利用哨兵简化实现难度针对链表的插入、删除操作,需要对插入第一个结点和删除最后一个结点的情况进行特殊处理。这样代码实现起来就会很繁琐,不简洁,而且也容易因为考虑不全而出错。如何来解决这个问题呢?哨兵就要登场了。哨兵,解决的是国家之间的边界问题。同理,这里说的哨兵也是解决“边界问题”的,不直接参与业务逻辑。还记得如何表示一个空链表吗?head=null 表示链表中没有结点了。其中 head 表示头结点指原创 2022-03-21 20:09:43 · 8603 阅读 · 0 评论 -
07-删除链表的倒数第N个节点
删除链表的倒数第N个节点1. 双指针的经典应用1.1 解法一1.2 解法二2. 其他方法leetcode题目链接1. 双指针的经典应用推荐大家使用哨兵节点,也就是虚拟头结点,这样方面处理删除实际头结点的逻辑。在对链表进行操作时,一种常用的技巧是添加一个哑节点(dummy node),它的 next 指针指向链表的头节点。这样一来,我们就不需要对头节点进行特殊的判断了。1.1 解法一思路:由于我们需要找到倒数第 n 个节点,因此我们可以使用两个指针 firs和 second 同时对链表进行遍历原创 2022-03-23 07:33:26 · 2446 阅读 · 0 评论 -
08-链表相交
链表相交1.题目2.思路3.C代码实现1.题目LeetCode 题目链接2.思路简单来说,就是求两个链表交点节点的指针。 这里要注意,交点不是数值相等,而是指针相等。先比较headA与headB的长度,设置坐标a和b ,遍历一遍headA和headB,得到lenA和lenB,若lenA>lenB,则让a往后跳(lenA-lenB)步,反之让b往后跳(lenB-lenA)步。再开始同步向后跳,直到a=b,退出并返回看如下两个链表,目前curA指向链表A的头结点,curB指向链表B的头结点原创 2022-03-24 08:51:27 · 177 阅读 · 0 评论 -
09-两个有序的链表合并
两个有序的链表合并1. 题目1. 题目LeetCode题目链接原创 2022-03-25 06:13:30 · 977 阅读 · 0 评论 -
10-求链表的中间结点
求链表的中间结点1.题目1.题目LeetCode题目链接原创 2022-03-26 16:24:27 · 298 阅读 · 0 评论 -
11-栈(基于数组的顺序栈)
栈1. 如何理解“栈”?2. 如何实现一个“栈”?2.1 基于数组的顺序栈2.2 基于链表的链式栈1. 如何理解“栈”?关于“栈”,有一个非常贴切的例子,就是一摞叠在一起的盘子。我们平时放盘子的时候,都是从下往上一个一个放;取的时候,我们也是从上往下一个一个地依次取,不能从中间任意抽出。后进者先出,先进者后出,这就是典型的“栈”结构。从栈的操作特性上来看,栈是一种“操作受限”的线性表,只允许在一端插入和删除数据。第一次接触这种数据结构的时候,就对它存在的意义产生了很大的疑惑。因为我觉得,相比数组和原创 2022-03-28 00:21:19 · 1862 阅读 · 0 评论 -
12-栈(基于链表的链式栈)
基于链表的链式栈原创 2022-03-28 22:55:54 · 2954 阅读 · 0 评论 -
13-队列基本知识
队列基本知识1如何理解“队列”?2. 顺序队列3.链式队列1如何理解“队列”?队列这个概念非常好理解。你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队。先进者先出,这就是典型的“队列”。我们知道,栈只支持两个基本操作:入栈 push()和出栈 pop()。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。所以,队列跟栈一样,也是一种操作受限的线性表数据结构。队列基于数组、链原创 2022-03-29 22:46:27 · 451 阅读 · 0 评论 -
14-循环队列实现(C语言)
添加链接描述1添加链接描述2原创 2022-03-30 23:47:38 · 1549 阅读 · 0 评论 -
15-使用栈实现队列的操作
用栈实现队列1.题目2. 思路3. 代码实现LeedCode题目链接1.题目2. 思路3. 代码实现原创 2022-03-31 22:18:48 · 161 阅读 · 0 评论 -
16-使用队列实现栈的操作
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar原创 2022-04-03 21:34:50 · 467 阅读 · 0 评论 -
17-删除字符串中所有重复项
删除字符串中所有重复项1. 题目2.思路2.1 使用栈的方式2.2 使用双指针的方式3.代码实现3.1 栈的方式 (C++)3.2 双指针的方式 (C语言)1. 题目LeetCode链接2.思路这道题目就像是我们玩过的游戏连连看,如果相同的元素放在挨在一起就要消除。可能我们在玩游戏的时候感觉理所当然应该消除,但程序又怎么知道该如果消除呢,特别是消除之后又有新的元素可能挨在一起。2.1 使用栈的方式本题要删除相邻相同元素,其实也是类似字符匹配问题,相同左元素相当于左括号,相同右元素就是相当于右原创 2022-04-04 22:49:22 · 5049 阅读 · 0 评论 -
18-有效的括号(栈)
有效的括号1. 题目2.思路3. 代码实现3.1 C++实现3.2 C实现1. 题目LeetCode题目链接2.思路由于栈结构的特殊性,非常适合做对称匹配类的题目。首先要弄清楚,字符串里的括号不匹配有几种情况。建议要写代码之前要分析好有哪几种不匹配的情况,如果不动手之前分析好,写出的代码也会有很多问题。先来分析一下 这里有三种不匹配的情况,1)第一种情况,字符串里左方向的括号多余了 ,所以不匹配。2)第二种情况,括号没有多余,但是 括号的类型没有匹配上。3)第三种情况,字符串里右原创 2022-04-05 11:32:10 · 1181 阅读 · 0 评论 -
19-逆波兰表达式求值(栈)
逆波兰表达式求值1.题目描述2. 思路3.代码实现3.1 c++实现4. 复杂度分析1.题目描述LeetCode题目链接逆波兰表达式由波兰的逻辑学家卢卡西维兹提出。逆波兰表达式的特点是:没有括号,运算符总是放在和它相关的操作数之后。因此,逆波兰表达式也称后缀表达式。看一下本题,其实逆波兰表达式相当于是二叉树中的后序遍历。 可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后续遍历的方式把二叉树序列化了,就可以了。原创 2022-04-10 20:20:30 · 1948 阅读 · 0 评论 -
20-滑动窗口最大值(队列)
滑动窗口最大值1. 题目1. 题目LeetCode题目链接题解动图原创 2022-04-11 23:59:05 · 170 阅读 · 0 评论 -
21-反转字符串
反转字符串1. 题目链接2. 思路3.代码实现3.1 c++实现3.2 c实现4.复杂度分析1. 题目链接LeetCode题目链接2. 思路双指针法对于字符串,我们定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。一共执行了 N/2次的交换。对于长度为 N 的待被反转的字符数组,我们可以观察反转前后下标的变化,假设反转前字符数组为 s[0] s[1] s[2] … s[N - 1],那么反转后字符数组为 s[N - 1] s[N -原创 2022-04-13 22:09:57 · 3806 阅读 · 0 评论 -
22-递归
递归1. 如何理解“递归”?2.递归需要满足的三个条件3. 如何编写递归代码?4.递归代码要警惕堆栈溢出5. 递归代码要警惕重复计算6.怎么将递归代码改写为非递归代码?1. 如何理解“递归”?递归是一种应用非常广泛的算法(或者编程技巧)。很多数据结构和算法的编码实现都要用到递归,比如 DFS 深度优先搜索、前中后序二叉树遍历等等。所以,搞懂递归非常重要,否则,后面复杂一些的数据结构和算法学起来就会比较吃力。去的过程叫“递”,回来的过程叫“归”。基本上,所有的递归问题都可以用递推公式来表示。2.递归需原创 2022-04-19 19:42:36 · 122 阅读 · 0 评论 -
23-经典排序算法概述
经典排序算法1.如何分析一个“排序算法”?1.1 排序算法的执行效率1.2 排序算法的内存消耗1.3 排序算法的稳定性排序算法太多了,有很多可能连名字都没听说过,比如猴子排序、睡眠排序、面条排序等。只掌握众多排序算法中的一小撮,也是最经典的、最常用的:冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。按照时间复杂度把它们分成了三类。1.如何分析一个“排序算法”?学习排序算法,我们除了学习它的算法原理、代码实现之外,更重要的是要学会如何评价、分析一个排序算法。那分析一个排原创 2022-04-20 23:16:01 · 218 阅读 · 0 评论