数据结构的基本概念
数据结构是相互之间存在一种或者多种特定关系的数据元素的集合。
数据结构包括逻辑结构和存储结构两个层次
逻辑结构分为四种类型:集合结构,线性结构,树形结构,图形结构。、
物理结构又叫存储结构,分为两种,顺序存储结构、链式存储结构。
逻辑结构
集合结构:数据元素同属一个集合,单个数据元素之间没有任何关系。
线性结构:类似于线性关系,线性结构中的数据元素之间是一对一的关系。
树形结构:树形结构中的数据元素之间存在一对多的关系。(各元素及元素关系所组成图形头似于树状图)。
图形结构:数据元素之间是多对多的关系。
存储结构
顺序存储结构是把数据元素放到地址连续的存储单元里面,其数据间的逻辑关系和物理关系是
致的。之前学习的数组就是一种顺序存储结构。
链式存储结构:是把数据元素存放在任意的存储单元里面,这组存储单元可以是连续的也可以
是不连续的。
数据类型和抽象数据类型
a、数据类型:一个值的集合及定义在这个值集上的一组操作的总称。
一般包括整型、实型、字符型等原子类型外,还有数组、结构体和指针等结构类型。
b、抽象数据类型
抽象数据类型(Abstract Data Type,ADT),类似C语言中的结构体以及C++语言中的类。
通俗的讲,抽象数据类型,泛指除基本数据类型以外的数据类型。
算法 (algorithm)是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作;此外,一个算法还具有下列5个重要特性:
1.有穷性:一个算法必须总是(对合法的输入值)在执行有穷步之后结束,且每一步都可在有穷时间内完成。
2.确定性:算法中每一条指令必须有确切的含义,读者理解时不会产生二义性。并且,在任何条件下,算法只有惟一的一条执行路径,即对于相同的输入只能得出相同的输出。
3.可行性:一个算法是能行的,即算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现的
4.输入:一个算法有零个或多个的输入,这些输入取自于某个特定的对象的集合。
5.输出:一个算法有一个或多个的输出,这些输出是同输入有着某些特定关系的量。
算法+数据结构=程序
算法设计的要求:
1.正确性
2.可读性
3.健壮性
4.高效性与低存储量
时间复杂度指算法中各语句执行时间的总和
for (i=1;i<=n;++i)//执行n+1次
for (j=1;j<=n;++j)//执行n(n+1)次
x=x+1;//执行n2次
语句执行次数:f(n)=2n^2+2n+1
算法的执行时间:T(n)=O(n^2)
1.最好时间复杂度,指的是算法计算量可能达到的最小值。
2.最坏时间复杂度,指的是算法计算量可能达到的最大值。
3.平均时间复杂度,是指算法在所有可能情况下,按照输入实例以等概率出现时,算法计算量的加权平均值。
算法的时间复杂度不仅与问题的规模有关,还与问题的其他因素有关。如某些排序的算法,其执行时间与待排序记录的初始状态有关为此,有时会对算法有最好、最坏以及平均时间复杂度的评价。
空间复杂度只需要分析辅助变量所占的额外空间。
空间复杂度:S(n)=O(f(n))
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)。
总结
简述下列概念:数据、抽象数据类型、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构。
数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。在有些情况下,数据元素也称为元素、结点、记录等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
数据对象:是性质相同的数据元素的集合,是数据的一个子集。
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。
存储结构:数据对象在计算机中的存储表示,也称为物理结构。
抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。
线性表的定义
由n(n>=20)个数据特性相同的元素构成的有限序列称为线性表,(n=0)的时候被称为空表。
一个数据元素可以是简单的一个数据,一个符号,也可以是复杂的若干个数据项的组合
顺序存储
线性表的顺序存储又被称为顺序表。
顺序存储表示:用一组地址连续的存储单元依次存储线性表的数据元素的方式,具有顺序存储结构的特点(数据间的逻辑关系和物理关系是一致的)
假设线性表L存储的起始位置为 LOC(A),sizeof(ElemType)是每个数据元素所占用存储空间的大小,则表L所对应的顺序存储如下图:
线性表的顺序存储结构是一种随机存取的存储结构,即通过首地址和元素序号为以在0(1)时间内找到指定的元素。由于线性表的长度可变,且所需最大存储空间随问题的不同而不同,在C/C++语言中通常使用动态分配的一维数组表示线性表。
线性表的链式实现
链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的),存放数据元素的结点至少包括两个域(指针域、数据域D,也可以包含若于个指针域和数据域)。双向链表和单向链表。
关于带头结点的单链表及不带头节点的单链表
首元结点:是指链表中存储第一个数据元素的结点。
头结点:是在首元素结点之前附设的一个结点,其指针指向首元结点。
头指针:是指向链表中第一个结点的指针。若链表设有头结点,则头指针所指结点为线性表的头结点;若链表不设头结点,则头指针所指结点为该线性表的首元结点。
单链表的基本操作:初始化
①生成新结点作为头结点,用头指针L指向头结点。
②头结点的指针域置空
单链表取值算法的平均时间复杂度为 O(n)
链表插入元素:
习题讲解:
栈和队列的定义与特点
栈:受约束的线性表,只允诛栈顶元素入栈和出栈
对栈来说,表尾端称为栈顶,表头端称为栈底,不含元素的空表称为空栈
先进后出,后进先出
怎么判断栈是空的还是满的?
top 指栈顶元素后一位置、S.top == 0时,栈空、S.top==stacksize 时,栈满
队列:受约束的线性表,只允许在队尾插入,在队头删除
先进先出,后进后出
顺序栈操作的实现:
入栈
出栈
循环队列的表示与操作的实现
在循环队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外尚需附设两个指针{front和rear 分别指示队列头元素及队列尾元素的位置。
为了在 C/C++语言中描述方便起见,在此我们约定:初始化建空队列时,令front=rear=0,每当插入新的队列尾元素时,“尾指针增 1";每当删除队列头元素时,“头指针增1”。因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置,如图所示。
怎么判断队列是满还是空?
1.少用一元素空间,即队列空间大小为m时,有m-1个元素就认为是队满。这样判断队空的条件不变,即当头、尾指针的值相同时, 则认为队空;而当尾指针在循环意义上加1后是等于头指针, 则认为队满。
2.另设一个标志位以区别队列是“空”还是 “满。
总结:
栈是限定仅在表尾进行插入或删除的线性表,又称为后进先出的线性表。栈有两种存储表示,顺序表示(顺序栈和链式表示(链栈)。栈的主要操作是进栈和出栈,对于顺序栈的进栈和出栈操作要注意判断栈满或栈空。
队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端删除元素。队列也有两种存储表示顺序表示(循环队列)和链式表示(链队)。
栈和队列的逻辑结构都和线性表一样,数据元素之间存在一对一的关系。
循环队列中少用一个元素判断队空或队满时:
队空的条件:Q.front == Q.rear
队满的条件:(Q.rear+ 1)%MAXQSIZE == Q.front
习题
串的定义和特点
串即字符串,是由零个或多个字符组成的有限序列,是数据元素为单个字符的特殊线性表。
串是内容受限的线性表,它限定了表中的元素为字符
串长:串中字符个数(n20):n=0 时称为空串
空白串:由一个或多个空格符组成的串
子串:串S中任意个连续的字符序列叫S的子串,S叫主串
当两个串的长度相等,并且各个对应位置的字符都相等时,才称这两个串相等
串的存储结构: 定长顺序存储、堆分配存储、块链存储
定长顺序存储:按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区,通常用定长字符数组来实现。堆分配存储:仍以一组地址连续的存储单元存放串值,但存储空间是在程序执行过程中动态分配而得。串的块链存储:串采用链式存储结构存储时称为链串。链串中的一个结点可以存储多个字符。通常将链串中每个结点所存储的字符个数称为结点大小。
数组
数组是线性表的推广,特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型。
列表
总结
串是内容受限的线性表,它限定了表中的元素为字符。
多维数组可以看成是线性表的推广,其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型。
广义表是另一种线性表的推广形式,表中的元素可以是称为原子的单个元素,也可以是一
子表,所以线性表可以看成广义表的特例。
习题
树
树是一种非线性的数据结构,它是由n个有限结点组成有层次关系的集合。
树具有以下特点,可以根据这些特点来判断一个数据结构是否是树
每个结点具有0个或多个子结点
每个子结点只有一个父结点
没有前驱的结为根结点
除了根结点外,每个子结点又可以由m棵不相关的子树组成
结点的度:结点拥有的子树数量称为结点的度树的度:树内各结点度的最大值,即上图D结点的度就
是此树的度
叶子:度为0的节点称为时子或终端节点
结点的层次和树的深度
结点的层次从根开始定义起,根为第一层,根的孩子为第二层,以此类推。树的深度(Depth)或高度是树中结点的最大层次。
森林:m棵互不相交的树的集合
二叉树
二叉树与树主要有以下区别:
二叉树每个结点至多只有两棵子树(即二又树中不能存在度大于 2 的结点
二叉树的子树有左右之分,其次序不能任意颠倒
即使树中某结点只有一棵子树,也要区分它是左子树还是右子树
二叉树的性质
完全二叉树
二叉树的顺序存储有很多缺点
二叉树的链式存储更好
二叉树的遍历:按某条搜索路径访问二叉树中每一个结点,使得每个结点被访问一次且仅被访问一次。遍历方法有4种:先序遍历,中序遍历,后序遍历,层次遍历。
先序遍历
中序遍历
后序遍历
层序遍历
哈夫曼树
哈夫曼编码
习题
图
图的定义与基本术语
图的存储结构:邻接矩阵
图的存储结构:邻接表
图的遍历
图的遍历:从图中某一顶点出发访遍图中其余结点,使每一个结点被访问且仅被访问一次
图的遍历通常有两种方法:深度优先搜索和广度优先搜索。它们对有向图和无向图都适用