数据结构与算法
文章平均质量分 67
按顺序梳理主要梳理数据结构知识,并提供C++代码实现
skywuuuu
这个作者很懒,什么都没留下…
展开
-
Floyd算法图解(内附核心代码)
图解伪代码# 初始化map = [[0, 3, INF, 7], [8, 0, 2, INF], [5, INF, 0, 1], [2, INF, INF, 0]]path = [[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]] for k in range(1, n+1): for i in range(1, n+1): for j in range(原创 2021-06-14 23:49:50 · 1858 阅读 · 0 评论 -
Dijkstra算法图解
介绍Dijkstra算法是一种贪心思想的算法,每一次它都会选取到顶点v的当前最短的路径并基于顶点v的边继续计算,直到遍历完所有的顶点。Dijkstra算法不支持权重为负的边,因为贪心算法一定会选中负权重的边从而可能错过最优解。图解伪代码# map[][]是邻接矩阵# 初始化for vertex in vertices: vertex['distance'] = INFINITY vertex['prev'] = Nonevertices[0]['distance'] = 0visit原创 2021-06-14 17:39:39 · 563 阅读 · 0 评论 -
Bellman-ford算法图解
介绍与Dijkstra算法不同,Bellman-ford能对付有负权重的边,而且可以检测negative cycle.假设V存的是所有的顶点(vertex),E存的是所有的边(edge),w(u, v)代表顶点u到顶点v的权重,PI[v]存的是从哪一个顶点到顶点v(PI[A]=s表示s->A)以这幅图为例子。伪代码初始化伪代码for v in V: d[v]=INFINITY PI[v]=''d[s]=0循环for i in range(1, len(V)): #原创 2021-06-14 16:27:07 · 6329 阅读 · 1 评论 -
图的深度优先搜索和广度优先搜索详解+代码实现
前言深度优先搜索其实不止可以用在图,也可以用在树,因为树可以看成一种特殊的,较为简单的图。在leetcode上,关于树的题目中经常会用到DFS和BFS以及它们的变体,所以掌握代码是很重要的深度优先搜索理解所谓深度优先,就是优先往下一层走。步骤理解起来很容易,让我们来看看步骤:挑一个顶点开始(一般按顶点存在数组中的顺序来,或者abcd…,1234…这种)访问它将该顶点入栈,并使用visited数组进行标记将栈中的顶点出栈访问它的有边的顶点重复第二个步骤至第五个步骤直到所有顶点均已被访原创 2021-05-29 19:04:09 · 1095 阅读 · 0 评论 -
代码实现:用C语言实现Stack,Queue,Graph的邻接矩阵,BFS和DFS还有拓扑排序
前言这个代码其实是我一年半前学习数据结构时敲下的,我检查了几遍应该是没有问题的,如果有更好的方法或哪里有bug,大家可以在评论区留言哦!代码实现#include <stdio.h>#include <stdlib.h>#define MaxVnum 100// 声明typedef char VexType;typedef int EdgeType;typedef struct graph Graph;typedef struct stack Stack;ty原创 2021-05-29 18:35:34 · 209 阅读 · 0 评论 -
图的基本概念
前言在学习计算机网络的时候,老师也提到了几种最短路径算法,用来计算一个节点到另一个节点的route,例如dijkstra,bellman-ford(我给它起外号叫铃铛人算法hhhhhh),现在就来顺便全面复习一波图吧。基本概念图中的每一个元素我们称之为顶点,每一个顶点和其他的顶点之间有边作为联系,边可以有权重来表示比如距离,关系远近等属性,一个顶点有几条边被称之为顶点的度是多少,我们可以把图按照边有没有方向分为有向图和无向图。对有向图来说,顶点可以指向其他几个顶点,也可以被其他顶点指向,也就有了出度(原创 2021-05-29 17:00:28 · 132 阅读 · 0 评论 -
入门必备:排序算法大汇总(代码实现)
前言假设都是以升序排序,定义个交换函数和打印函数。void swap(int& a, int& b) { int temp = a; a = b; b = temp;}void show(int arr[], int n) { for (int i = 0 ; i < n; i++) { cout << arr[i] << ", "; } cout << endl;}冒泡排序(Bubble原创 2021-05-28 21:46:39 · 126 阅读 · 5 评论 -
刷了100题树,我总结了这些经验
前言树的逻辑前序,中序,后序遍历->先根,再左子树和右子树原创 2021-05-05 10:43:49 · 91 阅读 · 0 评论 -
AVL树:图解左右旋单双旋(内附代码)
前言上一篇博客讲完了二叉搜索树,二叉搜索树在分配单元上有一些挺好的做法,非极端情况下查找的时间复杂度为O(logn)O(logn)O(logn),但是请看下面这种情况,如果我们要查找数字6,时间复杂度会退化为O(n)O(n)O(n),跟普通链表没什么差别了。所以我们需要一种方式来平衡一下这棵树,使得我们可以一直保持着比较快的搜索时间。重要概念那么我们应该在什么时候平衡呢?在每一次插入新节点时进行平衡,平衡的操作包括左单旋,右单旋,左双旋,右双旋。听起来十分复杂,但其实并没有,我们可以通过画图使得这原创 2021-03-22 16:02:37 · 1071 阅读 · 0 评论 -
详解二叉搜索树,增删改查都包圆(内附代码实现)
概念二叉搜索树是一种特殊的二叉树,其中左孩子一定比父节点小,右孩子一定比父节点大。递归思想在其中有巨大的作用。下面是我画的二叉树。我们用C语言来讲首先我们的Node是这样的:typedef struct BST{ int data; struct BST* lchild; struct BST* rchild;}BSTree;创建二叉查找树/增加节点递归的思想:递归函数的功能:把每一个节点都添加进二叉查找树中递归结束的条件:找到节点应该在的位置,然后进行插入原创 2021-03-21 10:16:47 · 269 阅读 · 0 评论 -
从树到二叉树基础概念全解析(内附代码)
树讲二叉树前先大概介绍一下树,此处先放图,树这个数据结构就是来源于生活中的树,把生活中的树倒过来,就是数据结构中的树了。和树有关的术语各结点的名称和关系根(root):下图1号孩子(child):比如下图7号是4号的孩子(如果是二叉树,则可以再细化为左孩子)父节点(parent):一个父节点可以有≥1\ge 1≥1个子节点,比如4号是7号和8号的父结点兄弟节点(siblings):具有相同父亲节点的是兄弟,比如7号和8号叶节点(leaf):没有孩子的节点是叶节点,比如5,9,10,12,原创 2021-03-20 15:47:28 · 607 阅读 · 0 评论 -
全面介绍散列表和冲突消除问题
散列表的概念散列表又被称作哈希表,是一种可以在O(1)时间内实现增删改查功能的强力技术,当然,为了实现这种目标,散列是无法被排序的。我们先通过一个简单的例子来理解一下这几个概念:读书的时候我们每个人都有长长的一串学号,假设学号的格式是专业码+入学年份+编号(比如123 2021 003),我们要储存同学的信息到系统中,而且要一秒输入学号查找到人,这里我们就可以用散列表了!因为只是储存一个专业的同一级的每个人,我们只需要以最后三位作为下标然后将每个人的信息存到下标对应的数组空间中就行了。其中,散列函数(Ha原创 2021-03-18 12:36:09 · 375 阅读 · 0 评论 -
排队的时候让我们来好好理理队列的结构(内附代码实现)
队列的概念排队是生活中非常常见的现象,比如我们排队进游乐场,排在你前面的肯定是比你早排队的人,排在你后面的肯定是比你晚排队的人,换成专业点的语言也就是FIFO(First In, First Out,先进先出) 这就是队列了。和栈支持入栈push()和出栈pop()类似,队列支持入队enqueue()和出队dequeue()的操作。enqueue()是从队尾塞一个元素进去,dequeue()是从队头拿一个元素出来。队列的实现基于链表实现的队列还是和栈很类似,栈是从头进从头出,队列是从尾进从头出。而基原创 2021-03-15 13:36:49 · 166 阅读 · 0 评论 -
简单又实用的栈实现和栈应用(内附实现代码)
栈的概念在正式讲栈的概念前,先举个例子,栈其实就像弹夹,我们把子弹一个一个压进去,开枪的时候最后一个压进去的子弹第一个被打出来。栈也有这样的特性:“FILO”(First In,Last Out),先进后出,后进先出。我们不难发现栈⊂\subset⊂数组或链表,那么为什么我们还需要栈而不直接使用数组或链表呢?因为在某些情况下我们不想让别人用其他的除了我们限定的方法处理数据。当我们要处理的数据满足上面FILO特性而且只被允许在一端push或pop时,栈是个很好的选择。栈的实现栈的链表实现跟数组实现差原创 2021-03-14 10:33:51 · 371 阅读 · 0 评论 -
学了这种理解,下次遇见链表再也不怕了
什么是链表在正式开始链表的认识前,我们先来回顾一下数组。数组是一种线性表,它用一串连续的内存空间来储存同一种类型的数据,而链表与数组唯一的区别就是它可以不用连续的内存空间来储存数据,这是如何实现的呢?没错,就是通过指针(有的语言,比如java,python,没有指针,但其实它们内部都有类似结构),指针储存的是它指向的变量的地址,通过该地址我们就能找到变量对应的值。这里简单举个例子,比如你要去朋友家里玩,那你自然要问朋友家里的地址,然后找到这个地址你就能找到朋友本人了,指针储存的地址可以理解为朋友家的地址。原创 2021-03-13 11:42:49 · 181 阅读 · 1 评论 -
数组——最简单的数据结构类型
数组的定义数组是一种线性表,它会被分配一块连续的内存空间来存储相同类型的元素。(参考维基百科,百度百科等的定义)1. 线性表简单从字面意思理解,线性表就是这个表的每个元素的分布是线性的,是在线的上面的。除了数组,后面要复习到的链表,队列,栈也可以说是线性表的其他几种表示类型,它们各有各的妙用。2. 连续的内存空间电脑会分配一段空间,比如从0000 0000 ~ 1111 1111,这一段都是属于某个数组的3. 相同类型的元素比如int a[10]里面存储的都是int类型的数据,每个相同类型的数原创 2021-03-11 09:52:18 · 410 阅读 · 0 评论 -
平均时间复杂度和均摊时间复杂度傻傻分不清?请看这篇文章
前言上一篇文章基础的时间复杂度和空间复杂度分析讲到了一些基础概念,比如big O,big Omega,big Theta等的定义,和分析时间复杂度的两大法则。因为最好时间复杂度(B(n)B(n)B(n))和最坏时间复杂度(W(n)W(n)W(n))的分析比较简单,所以我们直接跳过。在本篇文章中将着重讲解平均时间复杂度和均摊时间复杂度的区别。平均时间复杂度(A(n))通过概率论中学过的一些方法来对所有的情况进行出现概率上的分析,从而计算时间复杂度。比如我们举一个选择扛旗人的例子:现在星灵还缺一个扛旗人原创 2021-03-10 21:46:44 · 1141 阅读 · 2 评论 -
时间复杂度和空间复杂度基础
时间复杂度时间复杂度有好多种定义方式,什么big O,small o,big Omega,small omega,balabala,首先先了解几个概念:T(n)T(n)T(n)是Every-case time complexity,就是用来定义一个算法对于大小为nnn的对象所做的运算次数。有T(n)T(n)T(n)就还有W(n)W(n)W(n),W代表worst;B(n)B(n)B(n),B代表best;A(n)A(n)A(n),A代表average等等。Big O着重介绍以下Big O的定义,和原创 2021-03-10 17:32:23 · 365 阅读 · 0 评论 -
数据结构与算法知识结构全面梳理目录
表数组链表栈(stack)队列(queue)树简单二叉树二叉搜索树AVL树B树原创 2021-03-10 10:36:04 · 193 阅读 · 4 评论