附注说明:上图中删完尾节点之后,新链表的尾节点下标应为n-1。不过由于作图时只做了尾节点,故用图中的n2节点代替。
删除尾节点的代码如下:
- if(p->next==NULL)
- {
-
q->next=NULL;
- }
③. 删除非头尾节点,如图
删除非头尾节点的代码如下:
4.查询节点:在链表中找到你想要找的那个节点。此操作是根据数据域的内容来完成的。查询只能从表头开始,当要找的节点的数据域内容与当前不相符时,只需让当前节点指向下一结点即可,如此这样,直到找到那个节点。
附注:此操作就不在这用图和代码说明了。
5.修改节点:修改某个节点数据域的内容。首先查询到这个节点,然后对这个节点数据域的内容进行修改。
附注:同上
ok,链表的几种操作介绍完了,接下来我们来总结一下链表的几个特点。
链式存储结构的特点:
1.易插入,易删除。不用移动节点,只需改变节点中指针的指向。
2.查询速度慢:每进行一次查询,都要从表头开始,速度慢,效率低。
扩展阅读
链表:http://public.whut.edu.cn/comptsci/web/data/512.htm
第二节 树形存储结构
所谓树形存储结构,就是数据元素与元素之间存在着一对多关系的数据结构。在树形存储结构中,树的根节点没有前驱结点,其余的每个节点有且只有一个前驱结点,除叶子结点没有后续节点外,其他节点的后续节点可以有一个或者多个。
如下图就是一棵简单的树形结构:
说到树形结构,我们最先想到的就是二叉树。我们常常利用二叉树这种结构来解决一些算法方面的问题,比如堆排序、二分检索等。所以在树形结构这节我只重点详解二叉树结构。那么二叉树到底是怎样的呢?如下图就是一颗简单的二叉树:
附注:有关树的概念以及一些性质在此不做解释,有意者请到百科一览。
二叉树的类型描述如下:
- typedefstructtree
- {
-
chardata;
-
structtree*lchild,*rchild;
- }tree;
二叉树的操作:创建节二叉树,创建节点,遍历二叉树,求二叉树的深度。
1.创建二叉树:声明一棵树并为其申请存储空间。
- structtree*T=NULL;
-
T=(structtree*)malloc(sizeof(structtree));
2.创建节点:除根节点之外,二叉树的节点有左右节点之分。
创建节点的代码如下:
- structtree*createTree()
- {
-
charNodeData;
-
scanf("%c",&NodeData);
-
if(NodeData=='#')
-
returnNULL;
-
else
- {
-
structtree*T=NULL;
-
T=(structtree*)malloc(sizeof(structtree));
- T->data=NodeData;
- T->lchild=createTree();
- T->rchild=createTree();
-
returnT;
- }
- }
3.遍历二叉树:分为先序遍历、中序遍历、后续遍历。
①.先序遍历:若二叉树非空,则依次执行如下操作:
(1) 访问根结点;
(2) 遍历左子树;
(3) 遍历右子树。
如图:
先序遍历的代码如下:
- voidPreTravser(structtree*T)
- {
-
if(T==NULL)
-
return;
-
else
- {
-
printf("%c",T->data);
- PreTravser(T->lchild);
- PreTravser(T->rchild);
- }
- }
②.中序遍历:若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)访问根结点;
(3)遍历右子树。
如图:
中序遍历的代码如下:
- voidMidTravser(structtree*T)
- {
-
if(!T)
- {
-
return;
- }
-
else
- {
- MidTravser(T->lchild);
-
printf("%c",T->data);
- MidTravser(T->rchild);
- }
- }
③.后续遍历:若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)遍历右子树;
(3)访问根结点。如图:
后续遍历的代码如下:
- voidPostTravser(structtree*T)
- {
-
if(!T)
-
return;
-
else
- {
- PostTravser(T->lchild);
- PostTravser(T->rchild);
-
printf("%c->",T->data);
- }
- }
4.求二叉树的深度:树中所有结点层次的最大值,也称高度。二叉树的深度表示如下图:
求二叉树深度的代码如下:
- inttreeDeepth(structtree*T)
- {
-
inti,j;
-
if(!T)
-
return0;
-
else
- {
-
if(T->lchild)
- i=treeDeepth(T->lchild);
-
else
- i=0;
-
if(T->rchild)
- j=treeDeepth(T->rchild);
-
else
- j=0;
- }
-
returni>j?i+1:j+1;
- }
好了,二叉树的几种操作介绍完了。
拓展阅读
二叉树:http://student.zjzk.cn/course_ware/data_structure/web/DOWNLOAD/%CA%FD%BE%DD%BD%E1%B9%B9%D3%EB%CB%E3%B7%A82.htm
赫夫曼编码:http://blog.csdn.net/fengchaokobe/article/details/6969217
第三节 图型存储结构
所谓图形结构,就是数据元素与元素之间的关系是任意的,任意两个元素之间均可相关,即每个节点可能有多个前驱结点和多个后继结点,因此图形结构的存储一般是采用链接的方式。图分为有向图和无向图两种结构,如下图
通过图,我们可以判断两个点之间是不是具有连通性;通过图,我们还可以计算两个点之间的最小距离是多少;通过图,我们还可以根据不同的要求,寻找不同的合适路径。
1.图的结构有好几种,在实际应用中需根据具体的情况选择合适的结点结构和表结构。常用的有数组结构、邻接表。
①.数组结构
数组结构的类型描述如下:
- typedefcharVertexType;
-
typedefintEdgeType;
-
#definemaxvex100/***顶点的最大个数***/
-
typedefstruct
- {
-
VertexTypevexs[maxvex];
-
EdgeTypearc[maxvex][maxvex];
- }Mgraph;
附注:当前图为无向图时,图中某两个顶点VA和VB构成一条边时,其权值可表示为EdgeType arc[VA][VB];当前图为有向图时,图中某两个顶点VA和VB构成一条边时,并且是由VA指向VB,其权值可表示为EdgeType arc[VA][VB],如果是由VB指向VA,其权值可表示为EdgeType arc[VB][VA]。
②.邻接表
邻接表的类型描述如下:
- typedefcharVertexType;
-
typedefintEdgeType;
-
typedefstructEdgeNode
- {
-
intadjvex;
-
EdgeTypeweight;
-
structEdgeNode*next;
- }EdgeNode;
-
typedefstructVertexNode
- {
-
VertexTypedata;
-
EdgeNode*firstedge;
- }VertexNode,AdjList[MAXVEX];
-
typedefstruct
- {
- AdjListadjList;
-
intnumVertexes,numEdges;
- }GraphAdjList;
2.图的遍历:从图中的某一节点出发访问图中的其余节点,且使每一节点仅被访问一次。图的遍历算法是求解图的连通性问题、拓扑排序和求路径等算法的基础。图的遍历分为深度优先遍历和广度优先遍历,且它们对无向图和有向图均适用。
①. 深度优先遍历
定义说明:假设给定图G的初态是所有顶点均未曾访问过。在G中任选一顶点V为初始出发点,则深度优先遍历可定义如下:首先访问出发点V,并将其标记为已访问过;然后依次从V出发搜索v的每个邻接点W。若W未曾访问过,则以W为新的出发点继续进行深度优先遍历,直至图中所有和源点V有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。
深度遍历过程如下图:
②. 广度优先遍历
定义说明:假设从图中某顶点V出发,在访问了V之后一次访问V的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中还有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。换句话说,广度优先遍历图的过程是以V为起点,由近至远,依次访问和V有路径相同且路径长度为1,2,...的顶点。广度遍历过程如下图:
相关推荐
云存储架构是一种基于云计算理念的分布式存储系统,它通过集群应用、网格技术或分布式文件系统将大量异构存储设备整合在一起,形成一个统一的存储池,为用户提供数据存储和访问服务。这一概念源于分布式计算、并行...
本文将深入探讨iOS中的几种主要数据存储方式,包括:偏好设置、文件系统、SQLite数据库、Core Data以及归档与解档。 1. **偏好设置(UserDefaults)** 偏好设置,也称为用户默认值,是最简单的数据存储方式,适用...
C语言中的数据存储对齐是编译器为了提高内存访问效率和硬件兼容性而采用的一种策略。它涉及到如何在内存中安排数据结构的各个成员,确保数据读取和写入时能够快速高效地进行。对齐规则主要有以下几点: 1. **成员按...
结构化数据存储已经存在了几十年,是人们最熟悉的数据存储技术。大多数事务型数据库都是行式数据库,因为要处理来自软件应用程序的频繁数据写入。结构化数据存储的查询领域中有更多的创新,如列式文件格式的创新,它...
### 数据结构详解:Java排序算法 #### 排序概述 排序是计算机科学中一项基本而重要的操作,它涉及将一系列数据根据特定的标准进行排列。排序技术不仅应用广泛,而且是衡量算法效率的重要指标之一。本章节主要介绍...
该系统以存储设备为核心,通过应用层软件对外提供数据存储和业务服务。 大数据时代下的三种存储架构各有其特点和优势,但都不能满足大数据应用的需求。因此,需要根据不同的应用场景和需求,选择合适的存储架构,...
5. 数据存储结构: PLC在执行控制程序的同时,也会频繁地读写各种数据。数据存储区主要分为几个部分: - 输入/输出数据存储区(I/O区):存放来自传感器、执行器等现场设备的信号状态。 - 内部标志位存储区:用于...
OpenStack 架构详解 OpenStack 是一个开源的云计算平台,提供了一个操作平台或工具包,用于编排云计算资源。 OpenStack 由社区维护,包括 OpenStack 计算(Nova)、OpenStack 对象存储(Swift)和 OpenStack 镜像...
该系统以存储设备为核心,通过应用层软件对外提供数据存储和业务服务。 在大数据时代下,存储架构的演进是非常重要的。根据不同的应用场景和需求,需要选择合适的存储架构来满足业务需求。只有这样,才能满足大数据...
下面我将详细介绍几种常见的数据结构及其特点。 1. 线性表(Linear List) 线性表是最基本、最简单、也是最常用的一种数据结构。它是一组具有相同类型的数据元素的有限序列。线性表中的数据元素之间是一对一的关系...
在本题中,我们探讨了线性表的几个关键概念和操作,包括逻辑顺序与存储顺序的关系、随机存取、插入与删除操作的时间代价以及线性表的不同存储结构。 首先,线性表的逻辑顺序指的是元素的前后关系,而存储顺序则是指...
MySQL 索引数据结构详解 MySQL 索引是一种特殊的数据结构,它可以帮助快速定位和检索数据。索引的主要目的便是降低树的高度,从而提高查询效率。下面我们将详细介绍 MySQL 索引的数据结构和工作原理。 索引的存储 ...
- **解析**: 栈是一种逻辑数据结构,与其实现方式(如数组或链表)无关,因此与具体的存储结构无关。 **9. 线性结构与非线性结构** - **题目**: 以下数据结构中,哪一个是线性结构()? - **答案**: D. 串 - *...
云存储特别适合于处理高清化和网络化的视频监控数据,为大规模数据存储和管理提供了有效途径。 综上所述,大数据时代的存储架构必须具备高性能、高安全、高可靠以及灵活扩展的能力。从嵌入式NVR到X86 SAN,再到云...
数据结构是计算机科学与技术专业研究生入学考试中的核心科目之一,它主要研究如何在计算机中组织和管理数据,以便高效地进行存储、检索和处理。《考研数据结构1800试题详解》针对的是准备考研的学生,提供了大量数据...
Oracle存储过程是数据库管理系统Oracle中的一种重要特性,它是一组为了完成特定功能的SQL语句集,被编译存储在数据库中,用户可以通过调用它的名称来执行这些语句。存储过程的优势在于提高了效率,增强了安全性,并...