社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
一、数据结构绪论
数据结构的基本概念
数据结构是一门研究非数值计算的程序设计问题中,计算机的操作对象以及它们之间的关系和操作的学科。
数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据结构包含三个方面的含义:
逻辑结构:
物理结构:数据的逻辑结构在计算机中的表示,称此为物理结构,或称存储结构。
数据类型:一个值的集合以及定义在这个值集上的一组操作的总称。
抽象数据类型:通常由用户定义,用以表示应用问题的数据模型以及定义在该模型上的一组操作。
算法是描述计算机解决给定问题的操作过程,即为决解某一特定问题而由若干条指令组成的有穷序列。
算法的效率分析:
http://univasity.iteye.com/blog/1164707
事后统计法:收集该算法实际的执行时间和实际占用空间的统计资料。
事前分析估算法:在算法运行之前分析该算法的时间复杂度和空间复杂度,来判断算法的效率。
时间复杂度分析:
、
常见函数的时间复杂度按数量递增排列及增长率:
二、线性表
线性表的类型定义
线性表是n(n>0)个相同类型数据元素构成的有限序列,其中n为线性表的长度。
线性表的基本操作:
线性表的顺序表示和实现
线性表的顺序存储结构:用一组地址连续的存储单元依次存储线性表的元素。
线性表的顺序存储,也成为向量存储,又可以说是一维数组存储。线性表中结点存放的物理顺序与逻辑顺序完全一致,它叫向量存储。
线性表顺序存储结构在插入或删除数据元素时比较繁琐,但是它比较适合存取数据元素。
线性表的插入操作:在第i个元素之前插入一个元素时,需将第n至第i(共n-i+1)个元素向后移动一个位置。
线性表的删除操作:删除第i个元素时需将从第i+1至第n(共n-i)个元素一次向前移动一个位置
线性表的链式表示和实现
用一组任意的存储单元(可能不连续)存储线性表的数据元素。
在链式存储结构中,每个存储结点不仅包含数据元素本身的信息,还必须包含每个元素之间逻辑关系的信息,即包含直接后继结点的地址信息(指针域)。
逻辑顺序与物理顺序有可能不一致;属顺序存取的存储结构,即存取每个元素必须从第一个元素开始遍历,直到找到需要访问的元素,所以所花时间不一定相等。
链表的创建方式:
结点类的定义:
单链表的基本操作
插入方式——头插法:
插入方式——尾插法:
查找运算——按序号查找:在链表中,即使知道被访问结点的序号i,也不能像顺序表中那么直接按序号i访问结点,而只能从链表的头指针除法,顺着链域next逐个结点往下搜索,直至搜索到第i个结点为止。链表不是随机存取结构,只能顺序存取。
查找运算——按数值查找:
删除结点:将被删除结点的前驱指针连接被删除结点的后继指针
循环链表
表中尾结点的指针域指向头结点,形成一个环。从表中任意一个点出发都可以找到表中其他的结点。
循环链表的操作和线性链表的操作基本一致,但循环链表中没有NULL指针,故遍历操作时,终止条件不再是判断p或p.next是否为空,而是判断他们是否等于某一指定指针,如头指针或尾指针。
双向链表
双向链表是在单链表的每个结点里再增加一个指向其直接前驱的指针域prior。这样就形成了链表中有两个方向不同的链,故称为双向链表。
双线链表——头插法:
双向链表——尾插法:
插入操作
删除操作
三、栈和队列
栈的概念
栈是限制在表的一端进行插入和删除运算的线性表,通常称插入、删除的这一端为栈顶,另一端为栈底。当表中没有元素时成为空栈。
栈的进出顺序判断:
栈的基本操作:
顺序栈
顺序栈利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时由于栈的操作的特殊性,还必须附设一个位置指针top来动态地指示栈顶元素的顺序栈中的位置。通常以top=0表示空栈。
顺序栈的基本运算:
链栈:采用链表作为存储结构实现的栈。为便于操作,采用带头结点的单链表实现栈。因为栈的插入和删除操作仅限制在表头位置进行,所以链表的表头指针就作为栈顶指针。
顺序栈和链式栈的比较:实现链式栈和顺序栈的操作都是需要常数时间,即时间复杂度为O(1),主要从空间和时间两个方面考虑。初始时,顺序堆栈必须说明一个固定的长度,当堆栈不够满时,造成一些空间的浪费,而链式堆栈的长度可变则使长度不需要预先设定,相对比较节省空间,但是在每个节点中设置了一个指针域,从而产生了结构开销。
队列的概念
队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素。在队列中,允许插入数据一端成为队尾(rear),允许删除的那一端称为队头(front)。
队列的基本操作:
顺序队列
顺序队列利用一组地址连续的存储单元依次存放自队首到队尾的数据元素,同时由于队的操作的特殊性,还必须附两个位置指针front和rear来动态地指示队首元素和队尾元素在顺序队列中的位置。通常front=rear表示空队列。
队列同堆栈一样也有上溢和下溢现象。以外,队列中还存在“假溢出”现象。所谓“假溢出”是指在入队和出队操作中,头尾指针不断增加而不减小或只减小而不增加,致使被删除元素的空间无法重新利用,最后造成队列中有空闲空间,但是不能够插入元素,也不能够删除元素的现象。
链式队列:采用链表作为存储结构实现的队列。为便于操作,采用带头结点的单链表实现队列。因为队列的插入和删除操作位置不同,所以链表需要设置表头指针和表尾指针分别指队首和队尾。
循环队列
假设向量的空间是m,只要在入出队列时,将队首和队尾的指针对m做求模运算即可实现队首和队尾指针的循环,即队首和队尾指针的取值范围是0到m-1之间。
判断队空和队满的方法
四、数组和广义表
数组的定义
数组是我们熟悉的数据类型,数组中各元素具有统一的类型,并且数组元素的下标一般具有固定的上界和下界,因此,数组的处理比其它复杂的结构更为简单。
任何数组A都可以看作一个线性表。数组维数确定后,数据元素个数和元素之间的关系不再发生改变,适合顺序存储。
数组的基本操作
数组的顺序表示和实现
行优先顺序
列优先顺序
矩阵的压缩存储
有些特殊矩阵,非零元素呈某种规律分布或者矩阵中出现大量的零元素的情况下,会占用许多单元去存储重复的非零元素或零元素,这对高阶矩阵会造成极大的浪费,为了节省存储空间,对这类矩阵进行压缩存储——即为多个相同的非零元素只分配一个存储空间;对零元素不分配空间。
特殊矩阵:所谓特殊矩阵是指非零元素或零元素的分布有一定规律的矩阵,如对称矩阵、三角矩阵、对角矩阵等等。
对称矩阵
对称矩阵中元素关于主对角线对称,故只要存储矩阵中上三角或下三角中的元素,让每两个对称的元素共享一个存储空间,这样能节约近一半的存储空间。
n2 个元素可以压缩到 n(n+1)/2个空间中。
三角矩阵
以主对角线划分,三角矩阵有上三角和下三角两种。上三角矩阵它的下三角中的元素均为常数。下三角矩阵正好相反,它的主对角线上方均为常数。
稀疏矩阵
除了记录非零元素的值之外,还必须同时几下它所在的行和列的位置。稀疏矩阵的存储方法一般有三种:三元组法、行逻辑连接顺序表和十字链表法。
广义表
是由零个或多个原子或子表组成的优先序列,是线性表的推广。
广义表的存储结构
广义表中的数据元素可以具有不同的结构,因此,难以用顺序存储结构表示,通常采用链式存储结构,每个数据元素可用一个节点表示。由于广义表中有两种数据元素,因此需要有两种结构的节点——一种是表结点,一种是原子结点。
表结点由三个域组成:标志域、指示表头的指针的指针域和指示表尾的指针域;而原子域只需两个域:标志域和值域。
表结点由三个域组成:标志域、指示表头的指针域和指向下一个元素的指针;原子结点的三个域为:标志域、值域和指向下一个元素的指针。
五、树
树的定义
树的逻辑表示:树形表示法、文氏图表示法、凹入表示法、括号表示法。
结点:表示树中的元素,包括数据项及若干指向其子树的分支。
结点的度:结点拥有的子树树;树的度:一棵树中最大的结点度数
叶子结点:度为0的结点;分支结点:度不为0的结点;孩子:结点子树的根称为该结点的孩子;双亲:孩子结点的上层结点叫该结点的双亲;兄弟:同一双亲的孩子。
深度:树中结点的最大层次数。
有序树:树中各结点的子树从左至右是有次序的,不能互换。否则称为无序树。
树的性质
树中的结点数等于所有结点的度数加1。
度为m的树中第i层上至多有mi-1 个结点(i>=1)。
二叉树的概念
满二叉树:定义——一棵深度为k且具有2k-1个结点的二叉树。特点——每一层上的结点数都是最大结点数。
完全二叉树:定义——深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称为完全二叉树。
二叉树的性质
二叉树的第i层上至多有2i-1(i>=1)个结点。
深度为K的二叉树至多有2k-1个结点。
对任何一棵二叉树T,如果其叶子数为n0,度为2的结点数为n2,则n0=n2+1。
一个有n个结点的完全二叉树,编号最大的分支结点的编号是
一个有n个结点的完全二叉树,n0的个数是不小于n/2的最小整数。
二叉树的存储结构
用一组连续的存储单元存储二叉树的数据元素。在存储之前对二叉树的所有结点安排一个适当的序列,使得结点在这个序列中的相互位置能反应出结点之间的逻辑关系。
特点:结点间关系蕴含在其存储位置中;浪费空间,适于存满二叉树和完全二叉树。
二叉树的链式存储结构
用一个链表来存储一棵二叉树,二叉树中每一个结点用链表中的一个链结点来存储。
遍历二叉树
遍历方法:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!