数据结构

数据结构

数据结构是研究如何存储数据的学科

存储结构

  1. 线性表

    ​ 1.1 顺序表

    ​ 1.2 链表

    ​ 1.3 栈

    ​ 1.4 队列

  2. 树结构

    ​ 2.1 普通树

    ​ 2.2 二叉树

    ​ 2.3 线索二叉树

  3. 图存储结构

  4. 递归

线性表

同小朋友手拉手一样。每个元素都有且仅有一个与之相邻的元素(除首尾以外)。具备这种关系就可以使用线性表来存储。

注意

​ 线性表不是一种具体的存储结构,是顺序表链表的统称

顺序表

顺序表可以简单的理解为数组

链表

链表可以想象成用链子连接成的数据条。

链表详解

​ 使用顺序表时,需要提前申请一定的空间,这块存储空间的物理地址是连续的。使用链表则完全不同。链表是随用随申请。也就是说他的位置是随机的。

单链表

​ 为了给各个数据块建立“依次排列”的关系,链表给各数据块增设一个指针,每个数据块的指针都指向下一个数据块(最后一个数据块的指针指向 NULL),就如同一个个小学生都伸手去拉住下一个小学生的手,这样,看似毫无关系的数据块就建立了“依次排列”的关系,也就形成了链表。
单链表中有两个节点比较特殊,分别是第一个结点和最后一个结点。我们通常把第一个结点叫作头结点,把最后一个结点叫作尾结点。其中,头结点用来记录链表的基地址,有了它,我们就可以遍历得到整条链表。而尾结点特殊的地方是:指针不是指向下一个结点,而是指向一个空地址 NULL,表示这是链表上最后一个结点。对单链表而言,理论上来说,插入和删除节点的时间复杂度是 O(1),查询节点的时间复杂度是 O(n)。

循环链表
	然后还有在单链表的基础上扩展还有循环链表,循环链表和单链表的区别是尾节点指向了头结点,从而首尾相连,有点像贪吃蛇。
双向链表
	即用两个链子连起来的链表。一根链子指向下一个节点,另一根链子指向上一个节点。这样找到上一个节点只需要O(1)个复杂度。

正是因为这个节点,使得双向链表在插入和删除操作时比单向链表更高效。

		前面已经提到单链表插入、删除时间复杂度已经是 O(1) 了,但是这没有考虑还只是针对插入、删除操作本身而言,
		以删除为例,删除某个节点后,需要将其前驱节点的指针指向被删除节点的下一个节点,这样,我们还需要获取其前驱节点,
		在单链表中获取前驱节点的时间复杂度是 O(n),所以综合来看单链表的删除、插入操作时间复杂度也是 O(n),而双向链表则不然,
		它有一个指针指向上一个节点,所以其插入和删除时间复杂度才是真正的 O(1)。
双向循环链表
	其实就是将双向链表和循环链表组合起来
栈和队列

栈和队列隶属于线性表,是特殊的线性表,因为它们对线性表中元素的进出做了明确的要求。

中的元素只能从线性表的一端进出(另一端封死),且要遵循“先入后出”的原则,即先进栈的元素后出栈。

队列中的元素只能从线性表的一端进,从另一端出,且要遵循“先入先出”的特点,即先进队列的元素也要先出队列。

树存储结构

​ 树存储结构适合存储具有“一对多”关系的数据。

图存储结构

​ 图存储结构适合存储具有“多对多”关系的数据。

时间复杂度和空间复杂度

算法

即解决问题的办法。同一个问题,使用不同的算法,耗费的时间和资源是不同的。

算法VS程序

算法是解决问题的思路;程序是在心中有想法的前提下编写出来可以运行的代码。

好算法的标准

对于一个问题的算法来说,之所以称之为算法,首先它必须能够解决这个问题(称为准确性)。其次,通过这个算法编写的程序要求在任何情况下不能崩溃(称为健壮性)。

如果准确性和健壮性都满足,接下来,就要考虑最重要的一点:通过算法编写的程序,运行的效率怎么样。

运行效率体现在两方面:

  1. 算法的运行时间 (时间复杂度)
  2. 运行算法所需要的内存空间大小 (空间复杂度)

存储结构和数据的关系

  1. 线性表 用于存储 一对一 逻辑关系的数据

  2. 树结构 用于存储 一对多 逻辑关系的数据

  3. 图结构 用于存储 多对多 逻辑关系的数据

存储结构(物理结构)

如果选择集中存储,就使用顺序存储结构;反之,就使用链式存储。至于如何选择,主要取决于存储设备的状态以及数据的用途。

集中存储(底层实现使用的是数组)需要使用一大块连续的物理空间,假设要存储大小为 1G 的数据,
若存储设备上没有整块大小超过 1G 的空间,就无法使用顺序存储,此时就要选择链式存储,
因为链式存储是随机存储数据,占用的都是存储设备中比较小的存储空间,因此有一定几率可以存储成功。

什么是线性表

就是把所有的数据用一根线串起来,放到一个物理空间中

两种线性存储结构
  1. 数据集中存放(顺序存储结构 简称 顺序表)
  2. 数据分散存放(链式存储结构 简称 链表)
    ***重点 ****:数据存储的成功与否;取决于能否将数据完整的还原成它原本的样子

前驱和后继

另外,对于具有“一对一”逻辑关系的数据,我们一直在用“某一元素的左侧(前边)或右侧(后边)”这样不专业的词,其实线性表中有更准确的术语:
某一元素的左侧相邻元素称为“直接前驱”,位于此元素左侧的所有元素都统称为“前驱元素”;
某一元素的右侧相邻元素称为“直接后继”,位于此元素右侧的所有元素都统称为“后继元素”;

顺序表及初始化过程详解

顺序表存储数据时,会提前申请一块足够大小的物理空间,然后将数据依次存储起来,存储时做到数据元素之间不留一丝空隙。

递归

递归算不上数据结构和算法,只是一种编程技巧。很多算法会通过递归来实现,比如归并排序、快速排序、二分查找法等。递归,简单来讲就是在函数定义中调用函数自身

判断一个问题是否可以通过递归来解决,主要看它是否满足以下三个条件:

  1. 一个问题的解可以分解为几个子问题的解
  2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
  3. 存在递归终止条件

递归一定要有终止条件,否则会导致函数被无限调用最终致使内存溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值