数据结构
讲解数据结构
小黄TimTim仔
(2021-7-3开始写博客)喜欢学习的小黄,C++提升ing,周三到周日每天至少更新一篇
展开
-
(数据结构)图——图、顶点、无向边、无向图、有向边、有向图、简单图、无向完全图、有向完全图、稀疏图、稠密图、权、网、子图的相关概念
图的定义:图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E)。其中:G表示一个图,V是图G中顶点的集合,E是图G中边的集合。注意:1、线性表中我们把数据元素称为元素;树中将数据元素称为结点;在图中数据元素称为顶点。2、线性表中可以没有数据元素,称为空表;树中可以没有结点,称为空树;在图中不允许没有顶点。在定义中,若V是顶点的集合,则强调了顶点集合V有穷非空。3、线性表中,相邻的数据元素之间具有线性关系;树结构中,相邻两层的结点具有层次关系;在图中,任意两个顶点之间都有可能有关原创 2021-09-07 16:27:06 · 12218 阅读 · 3 评论 -
(数据结构)树转换为二叉树、森林转换为二叉树、二叉树转换为树、二叉树转换为森林及树与森林的遍历
1、树转换为二叉树(1)加线。在所有兄弟结点之间加一条线。(2)去线。对树中每个结点,只保留它与第一个孩子结点的连线,删除它与其他孩子结点之间的连线。(3)层次调整。以树的根结点为轴心,将整棵树顺时针旋转一定的角度,使之结构层次分明。注意第一个孩子是二叉树结点的左孩子,兄弟转换过来的孩子是结点的右孩子。注意:层次调整时很容易弄错左右孩子的关系,第一个孩子是二叉树结点的左孩子,兄弟转换过来的孩子是结点的右孩子。2、森林转换为二叉树(1)把每棵树转换为二叉树。(2)第一棵二叉树不动,从第二棵二原创 2021-09-07 12:07:24 · 1246 阅读 · 0 评论 -
(数据结构)线索二叉树——线索二叉树概念、线索二叉树结点结构、创建线索二叉树程序、遍历线索二叉树算法
线索二叉树:将指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。其实线索二叉树相当于把一棵二叉树变成一个双向链表,这有利于方便插入删除结点和查找某个结点的操作。线索化:对二叉树以某种次序遍历使其变为线索二叉树的过程。线索二叉树的结点结构:lchild - ltag - data - rtag - rchild其中:1、ltag为0使指向该结点的左孩子,为1时指向该结点的前驱。2、rtag为0使指向该结点的右孩子,为1时指向该结点的后继。3、在每个结点原创 2021-08-30 13:38:32 · 932 阅读 · 0 评论 -
(数据结构)二叉树的生成——扩展二叉树的概念及用递归算法生成二叉树
将二叉树中每个结点的空指针引出一个虚结点,其值为一特定值(#),这种处理后的二叉树为原二叉树的扩展二叉树。前序遍历序列为:AB#D##C##,生成一棵二叉树,实现算法如下:void CreateBiTree(BiTree *T){ TElemType ch; scanf("%c", &ch); if (ch == '#') *T = NULL; else { *T = (BiTree) malloc (sizeof(BiTNode)); if (!*T)原创 2021-08-30 12:24:16 · 404 阅读 · 0 评论 -
(数据结构)二叉树的遍历——前序遍历、中序遍历、后序遍历、层序遍历 及 前中后序遍历的算法
二叉树的遍历:指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅访问一次。二叉树的遍历方法:1、前序遍历若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。(根——左——右)2、中序遍历若二叉树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。(左——根——右)3、后序遍历若二叉树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结原创 2021-08-26 16:18:31 · 606 阅读 · 0 评论 -
(数据结构)二叉树——满二叉树、完全二叉树、概念、特点、二叉树的性质、二叉树的顺序存储结构及二叉链表
二叉树的定义二叉树:n(n≥0)个结点的有限集合,该集合或者为空集(又称空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。二叉树的特点1、每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。注意不是只有两棵子树,没有子树或者有一棵子树都是可以的。2、左子树和右子树是有顺序的,次序不能任意颠倒。3、即使树中某结点只有一棵子树,也要区分它是左子树和右子树。二叉树具有五种基本形态:1、空二叉树。2、只有一个根结点。3、根结点只有左子树。4、根结点原创 2021-08-26 11:49:31 · 2973 阅读 · 0 评论 -
(数据结构)树——概念、常规操作指令、存储方式及双亲表示法、孩子表示法和孩子兄弟表示法
树:n(n≥0)个结点的有限集,是一种一对多的数据结构。当n=0时称为空树。在任意一棵非空树中:(1)有且仅有一个特定的称为根的结点;(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......、Tm,其中每一个集合本身又是一棵树,并且称为根的子树。树的定义还需要强调两点:(1)n>0时根结点是唯一的,不可能存在多个根结点,数据结构的树只能有一个根结点。(2)m>0时,子树的个数没有限制,但它们一定是互不相交的。结点分类1、树的结点包原创 2021-08-26 10:07:29 · 875 阅读 · 0 评论 -
(数据结构)串——概念、常规操作指令、串的顺序存储结构、串的链式存储结构
串:由零个或多个字符组成的有限系列,又名叫字符串。例如:s = "a1a2a3...an"(n>=0),其中s是串的名称,用双引号(或者单引号)括起来的字符序列部分是串的值。其中引号部分不属于串的内容,双引号里面可以是字母、数字或其他字符,其中ai的i就是字符在串的第n个位置,串中的字符数目n称为串的长度。空串:零个字符的串,长度为0,可直接用""""(两双引号)表示。注意:串的相邻字符之间具有前驱和后继的关系。1、空格串:只包含空格的串。2、空格串与空串的区别:空格串是有内容有长原创 2021-08-19 10:30:11 · 862 阅读 · 0 评论 -
(数据结构)队列——概念、循环队列、链队列、队列的常规操作及循环队列和链队列的入队、出队代码例子
队列:只允许在一端进行插入操作,在另一端进行产出操作的线性表。队列是一种先进先出的线性表(简称FIFO)。其中允许插入操作的一端称为队尾,允许删除操作的一端称为队头。例如队列a=(a1,a2,a3,...,an),其中a1是队头元素,an是队尾元素。这就像我们排队买奶茶一样,队头第一位买完就优先出列,后面先买奶茶的话,你就得排在队列的最后,所以删除时,我们总是从a1开始,插入时,在队尾插入。队列的应用:键盘进行各种字母或数字的输入、记事本软件上的输出等。队列的常规操作指令:InitQueue原创 2021-08-18 18:36:59 · 1351 阅读 · 0 评论 -
(C/C++)递归——斐波那契数列(用C/C++编写迭代和递归函数代码)
之前我们讲过递归的定义,今天学习一下运用到递归的斐波那契数列。递归的定义:在定义一个过程或函数时,出现直接或间接调用自己的成分,称之为递归。递归函数:一个直接调用自己或者通过一系列的调用语句间接地调用自己的函数。每个递归定义必须至少有一个条件,满足时递归不在进行,即不再引用自身而是返回值退出。斐波那契数列就是解决兔子繁殖计算的问题,问题如下:兔子从出生两个月后就有繁殖能力,一对兔子每个月可以生出一对兔子。加入兔子不死,一年后有繁殖多少对兔子?思路:新出生的兔子为例,第一个月——1对,原创 2021-08-15 16:01:20 · 2053 阅读 · 0 评论 -
(数据结构)栈的链式存储结构(链栈)的进栈操作和出栈操作——程序例子
既然有栈的顺序存储结构,那么也存在有栈的链式存储结构。栈的顺序存储结构称为顺序栈。栈的链式存储结构称为链栈。因为单链表有头指针,而栈顶指针也是必须的,所以我们可以把栈顶放在单链表的头部,此时链表有了栈顶在头部,这样单链表的头结点已经没有作用了,所以通常对链栈来说是不需要头结点的。顺序栈容易出现栈满的情况,而对链栈来说是基本不可能出现栈满的情况的,除非使用的内存空间已经用完了,这样的话你的电脑已经99%处于死机的状态了。链表的空栈:链表的头指针指向空。链栈的进栈操作:Status原创 2021-08-15 14:57:31 · 2581 阅读 · 0 评论 -
(数据结构)两栈共享空间——程序实现例子
栈的顺序存储结构只准栈顶输入元素,因此不存在线性表的插入建和删除时需要移动元素的问题。但是这样会导致内存不够用的问题,顺序栈必须事先确定数组存储空间大小,如果存储空间满了,就需要程序员进行编程操作扩展数组的容量。这也太麻烦了,一个不行,我用两个!找两个相同类型的栈,同时在两个栈里各自开辟数组空间,漂亮!但是没想到:第一个已经满了,再存储元素的话就会溢出,另一个栈存储空间还很多。这不是浪费吗?我们可以反过来想:用一个数组存储两个栈。这样不就解决了嘛。数组有两个端点,两个栈就有两个栈顶,我们可以让一原创 2021-08-15 14:15:31 · 415 阅读 · 0 评论 -
(数据结构)顺序栈——概念、进栈操作及出栈操作(程序例子)
我们了解一下,栈其实也是一个线性表,栈元素是具有线性关系,即前驱后继关系,它只是一种特殊的线性表。既然栈是线性表的特例,我们知道线性表是有顺序存储结构的,那么栈也是可以顺序存储的,栈的顺序存储是线性表顺序存储的简化,其中栈的顺序存储简称为顺序栈。...原创 2021-08-14 13:34:19 · 3963 阅读 · 0 评论 -
(数据结构)栈(LIFO结构)——概念、进栈、出栈、先进后出的特性
什么叫做栈?举个简单的例子:给手枪装子弹,最先进去的子弹在弹夹的最后一个位置,最后的一个子弹在弹夹的首位,这就是栈最好理解的例子了。栈运用的软件例子:word文档的撤销键、浏览器的后退键,美图秀秀p图的撤销键等栈的定义:栈是限定仅在表尾进行插入和删除操作的线性表。我们将允许插入的删除的一端叫做栈顶,另外一端叫做栈底,栈是一种后进先出的数据结构,所以称为后进先出的线性表,简称LIFO结构。空栈:不含任何数据元素的栈。注意:1、栈是一个线性表,栈里面的元素具有线性关系,也就是我们前面说原创 2021-08-13 14:33:56 · 2783 阅读 · 0 评论 -
(数据结构)循环链表和双向链表——概念及插入删除的程序例子
循环链表:将单链表的终端结点的指针端由空指针改为指向头结点,这样就会把整个单链表形成一个环,这种头尾相连的单链表也称单循环链表。单链表与循环链表的差异:原来判断怕p->next是否为空,现在改为p->next不等于头结点,则循环继续。我们也可以把两个循环链表合并成一个表,只要操作两个循环链表的尾指针就行了。现在是A循环链表:头结点是rearA->next 尾指针是rearAB循环链表:头结点rearB->next,头结点的下一个结点是rearB->next-..原创 2021-08-13 11:48:22 · 259 阅读 · 0 评论 -
(数据结构)静态链表——概念、插入与删除(程序)、优缺点
静态链表:用数组描述的链表。数组的元素是由data和cur两个数据域组成的,其中:1、数据域data是用来存放数据元素的。2、数据域cur相当于链式存储结构的next指针,用来存放该元素的后继在数组中的下标,通常把cur称为游标。我们在创建静态链表时,为了随时可以插入数据,会建立一个较大的数组,防止内存过小导致溢出。在创建数组时,我们对数组第一个元素和最后一个元素不做存放数据的处理。数组逻辑上分为两个链表:备用链表(空闲的节点)和数据链表(已被使用的节点)。备用链表:未被使用的数组元素。原创 2021-08-13 10:52:57 · 622 阅读 · 0 评论 -
(数据结构)单链表的创建和删除——算法思路+程序例子
知识回顾:顺序存储结构的创建,就是一个数组的初始化,相当于声明一个类型和大小的数组并赋值的过程。顺序存储结构是集中的,链式存储结构是分散的,它是一个动态结构。对于链表来说,它占用的空间大小和位置是不需要预先分配划定的,可按照实际需求即时生成。一、单链表整表创建的算法思路:1、声明一个指针p和变量i;2、初始化一个空链表L;3、让L的头结点的指针指向NULL,即创建一个带头结点的单链表;4、循环结构:a、生成一个新结点赋值给p;b、随机生成一个数字赋值给p的数据域p->data;c原创 2021-08-12 16:36:25 · 1110 阅读 · 0 评论 -
(数据结构)链表的读取、插入及删除——算法思路+程序例子
一、获取链表的第i个数据的算法思路:1、声明一个指针p指向链表的第一个结点,初始化j从1开始;2、当j < i 时,遍历链表,让指针p向后移动,不断指向下一个结点,++j;3、若到链表末尾p为空时,则说明第i个结点不存在;4、若3不成立,则说明查找成功,返回结点p的数据;算法程序例子:Status GetElem(LinkList L, int i, ElemType *e){ int j ; LinkList p; //声明指针p p = L->next; //p指针指原创 2021-08-12 15:16:11 · 1808 阅读 · 0 评论 -
(数据结构)线性表三——链式存储结构(链表)
知识补充:顺序储存结构:也称为顺序表。顺序表在存储数据时,会提前找到一块足够存放这些数据的内存空间,然后将数据一个一个的存储进去。链式存储结构:称为链表,也称为单链表。链表与顺序表不同,它可以把数据存储到不同的位置,不像顺序表只存放在一个位置上。链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素,其中这组存储单元可以是连续的,也可以是不连续的,所以这些数据元素可以存在内存未被占用的任意位置。顺序存储结构与链式存储结构的区别:1、顺序存储结构中,每个数据元素在存储的时候只需要存储数据元素原创 2021-08-12 14:07:52 · 1241 阅读 · 0 评论 -
(数据结构)线性表(三)——顺序存储结构的插入和删除(程序例子+算法思路)
获得元素的操作代码:#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0typedef int Status;Status GetElem(SqList L, int i, ElemType *e){ if(L.length == 0 || i < 1 || i > L.length) return ERROR; *=L.data[i - 1]; return OK;}插入算法的思路:1、如果插入位置不.原创 2021-08-07 16:20:30 · 1276 阅读 · 0 评论 -
(数据结构)线性表(二)——顺序存储结构
线性表的顺序存储结构——在一段地址连续的存储单元依次存储线性表的数据元素。举个简单的例子:在内存中寻找一块空地,依次有顺序地把一定内存空间进行占位,然后把相同数据类型的数据元素依次存放在这块空地里。其中一维数据可以实现顺序储存结构,例如:把第一个数据元素存到数组下标为0的位置中,然后将线性表的相邻元素依次存储进去数组相邻的位置。内存的第一个位置存放存储空间的起始位置,相当于数组的第一个元素位置存放的是数组的地址,其数组的长度就是这个最大存储容量。其中顺序存储结构需要三个属性:1、存储空间原创 2021-08-07 15:24:47 · 389 阅读 · 0 评论 -
(数据结构)线性表(一)——概念及常规操作指令
线性表(List):零个或多个数据元素的有限序列。线性表是一个序列,元素之间是有顺序的,线性表强调是有限的,元素个数自然也是有限的,而我们计算机处理对象都是有限的,那些无限的数列只是一个概念。现在有一个线性表,{a(1),...., a(i-1), a(i), a(i+1),...., a(n)},我们来看一下,表中的a(i-1)是在a(i)的前面,领先于a(i),同理a(i)领先于a(i+1),所以将a(i-1)是a(i)的直接前驱元素,a(i+1)是a(i)的直接后继元素。当i=1,2,3,原创 2021-08-07 14:29:13 · 151 阅读 · 0 评论