一:数据结构绪论
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构分为逻辑结构和物理结构
逻辑结构:是指数据对象中数据元素之间的相互关系 分为集合结构、线性结构、树形结构、图形结构。
物理结构:是指数据的逻辑结构在计算机中的存储方式 分为顺序存储结构、链式存储结构。
二:算法
算法:解决特定问题求解步骤的描述,在计算机中为指令的有限序列,并且每条指令表示一个或多个操作。
算法的特性:有穷性、确定性、可行性、输入、输出。
算法设计的要求:正确性、可读性、健壮性、高效率和低存储量需求。
算法的度量方法:事后统计方法、事前分析估算方法。
推导时间复杂度大O阶:
1.用常数1取代运行时间中的所有加法常数。
2.在修改后的运行次数函数中,只保留最高阶项。
3.如果最高阶存在且不是1,则去除与这个项相乘的常数。
得到的结果就是大O阶。
常见时间复杂度所耗时间的大小排列:
O(1)
三:线性表
线性表:零个或多个数据元素的优先序列。
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
存储器中的每个存储单元都有自己的编号,这个编号称为地址。
线性表顺序存储结构的优缺点:
优点:无须为表示表中元素之间的逻辑关系而增加额外的逻辑空间。可以快速地存取表中任何位置的元素。
缺点:插入和删除操作需要移动大量元素。当线性长度变化较大时,难以确定存储空间的容量。造成存储空尽的“碎片”。
线性表的链式存储结构,用一组任意的存储单元存储线性表的数据元素。这组存储单元可以是连续的,也可以是不连续的。
链式结构中,除了要存储数据元素信息外,还要存储它的后继元素的存储地址。
存储数据元素信息的域称为数据域,存储直接后继位置的域称为指针域。
指针域中存储的信息称作指针或链。
两部分信息组成数据元素的存储映像,称为结点。
n个结点链结成一个链表,即为线性表的链式存储结构。
如果链表的每个结点中只包含一个指针域,则叫做单链表。
链表中第一个结点的存储位置叫做头指针。
有时,我们为了更加方便地对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点
结点由存放数据元素的数据域存放后继结点地址的指针域组成。
对于插入删除数据越频繁的操作,单链表表的效率优势就越明显。
单链表结构和顺序存储结构对比:
存储分配方式:
顺序存储结构用一段连续的存储单元依次存储线性表的数据元素。
单链表采用链式存储结构,用一组任意的存储单元存放线性表元素。
时间性能:
1.查找:
顺序存储结构O(1)
单链表O(n)
2.插入和删除:
顺序存储结构需要平均移动表长一半的元素,时间为O(n)
单链表在线出某位置的指针后,插入和删除 时间仅为O(1)
3.空间性能:
顺序存储结构需要预分配存储空间,分大了浪费,分小了易发生上溢。
单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。
让数组的元素由两个数据域组成,data和cur。也就是说数组每一个下标都对应一个data和一个cur。数据域data,用来存放数据元素,也就是我们要处理的数据;而游标cur相当于单链表中的next指针,存放该元素的后继在数组中的下标。这种用数组描述的链表叫做静态链表。
静态链表的优点:在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点。
静态链表的缺点:没有解决连续存储分配带来的表长难以确定的问题,失去了顺序存储结构随机存取的特性。
将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环列表,简称循环链表。
双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。在双向链表中的结点中都有两个指针域,一个指向直接后继,另一个指向直接前驱。
四:栈和队列
1.栈
栈是限定仅在表尾进行插入和删除操作的线性表。
允许插入删除的一端称为栈顶,另一端称为栈底,不含任何元素的栈称为空栈。
栈又称为后进先出的线性表,简称LIFO结构。
栈的插入操作,叫做进栈,也称压栈、入栈。
栈的删除操作,叫做出栈,也有的叫做弹栈。
如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈。
一个直接调用自己或通过一系列调用语句间接地调用自己的函数,称为递归函数。
每个递归定义必须至少有一个条件,满足时递归不再进行,即不再引用自身而返回值退出。
迭代与递归的区别:迭代使用的是循环结构,递归使用的是选择结构。
如果是两个相同数据类型的栈,则可以用数组的两端作栈底的方法来让两个栈共享数据,最大化利用数组的空间。
2.队列
队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性表。
允许插入的一端称为队尾,允许删除的一端称为队头。
队列又称为先进先出的线性表,简称FIFO结构。
为避免数组插入和删除时需要移动数据,于是引入了循环队列,使得队头和队尾可以在数组中循环变化。解决了移动数据的时间损耗,使得本来插入和删除时O(n)的时间复杂度变成了O(1)。
五:串
串是由零个或多个字符组成的有限序列。
六:树
树是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树中:(1)有且仅有一个特定的称为根的结点;(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......Tm,其中每一个集合本身又是一棵树,并称为根的子树。
树的结点包含一个数据元素及若干指向其子树的分支。结点拥有的子树数称为结点的度。度为0的结点称为叶结点或终端结点;度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。树的度是树内各结点的度的最大值。
结点的子树的根称为该结点的孩子(Child),相应地,该结点称为孩子的双亲(Parent)同一个双亲的孩子之间互称兄弟(Slibling)。结点的祖先是从根到该结点所经分支上的所有结点。反之,以某结点为根的子树中的任一结点都称为该结点的子孙。
结点的层次从根开始定义起,根称为第一层,根的孩子为第二层。树中结点的最大层次称为树的深度或高度。
如果将该树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树为有序树,否则称为无序树。
森林是m(m>=0)课互不相交树的集合。
线性表与树对比:
线性结构:
第一个数据元素:无前驱
最后一个数据元素:无后驱
中间元素:一个前驱,一个后驱
树结构:
根结点:无双亲,唯一
叶结点:无孩子,可以多个
中间结点:一个双亲多个孩子
树的存储结构三种表示法:双亲表示法、孩子表示法、孩子兄弟表示法。
二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
二叉树特点:
每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。注意不是只有两颗子树,而是最多有。没有子树或者有一颗子树都是可以的。
左子树和右子树是有顺序的,次序不能任意颠倒。
即使树中某结点只有一颗子树,也要区分它是左子树还是右子树。
二叉树具有五种基本形态:
1.空二叉树。
2.只有一个根结点。
3.根结点只有左子树。
4.根结点只有右子树。
5.根结点既有左子树又有右子树。
所有结点都只有左子树的二叉树叫左斜树。所有结点都只有右子树的二叉树叫有斜树。这两者统称为斜树。
在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树其为满二叉树。