c语言+线性表抽象数据类型定义,存储结构,应用

合集下载

C语言中都有哪些常见的数据结构你都知道几个?

C语言中都有哪些常见的数据结构你都知道几个?

C语⾔中都有哪些常见的数据结构你都知道⼏个?上次在⾯试时被⾯试官问到学了哪些数据结构,那时简单答了栈、队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了⼀下⼏种常见的数据结构,原来我们学过的数据结构有这么多~⾸先,先来回顾下C语⾔中常见的基本数据类型吧O(∩_∩)OC语⾔的基本数据类型有:整型int,浮点型float,字符型char等等添加描述那么,究竟什么是数据结构呢?数据结构是计算机存储、组织数据的⽅式。

数据结构是指相互之间存在⼀种或多种特定关系的数据元素的集合⼤部分数据结构的实现都需要借助C语⾔中的指针和结构体类型下⾯,进⼊今天的重点啦O(∩_∩)O⼏种常见的数据结构(1)线性数据结构:元素之间⼀般存在元素之间存在⼀对⼀关系,是最常⽤的⼀类数据结构,典型的有:数组、栈、队列和线性表(2)树形结构:结点间具有层次关系,每⼀层的⼀个结点能且只能和上⼀层的⼀个结点相关,但同时可以和下⼀层的多个结点相关,称为“⼀对多”关系,常见类型有:树、堆(3)图形结构:在图形结构中,允许多个结点之间相关,称为“多对多”关系下⾯分别对这⼏种数据结构做⼀个简单介绍:1、线性数据结构:典型的有:数组、栈、队列和线性表(1)数组和链表a、数组:存放着⼀组相同类型的数据,需要预先指定数组的长度,有⼀维数组、⼆维数组、多维数组等b、链表:链表是C语⾔中⼀种应⽤⼴泛的结构,它采⽤动态分配内存的形式实现,⽤⼀组任意的存储单元存放数据元素链表的,⼀般为每个元素增设指针域,⽤来指向后继元素c、数组和链表的区别:从逻辑结构来看:数组必须事先定义固定的长度,不能适应数据动态地增减的情况;链表动态地进⾏存储分配,可以适应数据动态地增减的情况,且可以⽅便地插⼊、删除数据项(数组中插⼊、删除数据项时,需要移动其它数据项)从内存存储来看:(静态)数组从栈中分配空间(⽤NEW创建的在堆中), 对于程序员⽅便快速,但是⾃由度⼩;链表从堆中分配空间, ⾃由度⼤但是申请管理⽐较⿇烦从访问⽅式来看:数组在内存中是连续存储的,因此,可以利⽤下标索引进⾏随机访问;链表是链式存储结构,在访问元素的时候只能通过线性的⽅式由前到后顺序访问,所以访问效率⽐数组要低(2)栈、队列和线性表:可采⽤顺序存储和链式存储的⽅法进⾏存储顺序存储:借助数据元素在存储空间中的相对位置来表⽰元素之间的逻辑关系链式存储:借助表⽰数据元素存储地址的指针表⽰元素之间的逻辑关系a、栈:只允许在序列末端进⾏操作,栈的操作只能在栈顶进⾏,⼀般栈⼜被称为后进先出或先进后出的线性结构顺序栈:采⽤顺序存储结构的栈称为顺序栈,即需要⽤⼀⽚地址连续的空间来存储栈的元素,顺序栈的类型定义如下:添加描述链栈:采⽤链式存储结构的栈称为链栈:添加描述b、队列:只允许在序列两端进⾏操作,⼀般队列也被称为先进先出的线性结构循环队列:采⽤顺序存储结构的队列,需要按队列可能的最⼤长度分配存储空空,其类型定义如下:添加描述 链队列:采⽤链式存储结构的队列称为链队列,⼀般需要设置头尾指针只是链表的头尾结点:添加描述c、线性表:允许在序列任意位置进⾏操作,线性表的操作位置不受限制,线性表的操作⼗分灵活,常⽤操作包括在任意位置插⼊和删除,以及查询和修改任意位置的元素顺序表:采⽤顺序存储结构表⽰的线性表称为顺序表,⽤⼀组地址连续的存储单元⼀次存放线性表的数据元素,即以存储位置相邻表⽰位序相继的两个元素之间的前驱和后继关系,为了避免移动元素,⼀般在顺序表的接⼝定义中只考虑在表尾插⼊和删除元素,如此实现的顺序表也可称为栈表:添加描述线性表:⼀般包括单链表、双向链表、循环链表和双向循环链表单链表:添加描述 双向链表:添加描述线性表两种存储结构的⽐较:顺序表: 优点:在顺序表中,逻辑中相邻的两个元素在物理位置上也相邻,查找⽐较⽅便,存取任⼀元素的时间复杂度都为O(1) 缺点:不适合在任意位置插⼊、删除元素,因为需要移动元素,平均时间复杂度为O(n)链表: 优点:在链接的任意位置插⼊或删除元素只需修改相应指针,不需要移动元素;按需动态分配,不需要按最⼤需求预先分配⼀块连续空空 缺点:查找不⽅便,查找某⼀元素需要从头指针出发沿指针域查找,因此平均时间复杂度为O(n)2、树形结构:结点间具有层次关系,每⼀层的⼀个结点能且只能和上⼀层的⼀个结点相关,但同时可以和下⼀层的多个结点相关,称为“⼀对多”关系,常见类型有:树、堆(1)⼆叉树:⼆叉树是⼀种递归数据结构,是含有n(n>=0)个结点的有限集合,⼆叉树具有以下特点:⼆叉树可以是空树;⼆叉树的每个结点都恰好有两棵⼦树,其中⼀个或两个可能为空;⼆叉树中每个结点的左、右⼦树的位置不能颠倒,若改变两者的位置,就成为另⼀棵⼆叉树(2)完全⼆叉树:从根起,⾃上⽽下,⾃左⽽右,给满⼆叉树的每个结点从1到n连续编号,如果每个结点都与深度为k的满⼆叉树中编号从1⾄n的结点⼀⼀对应,则称为完全⼆叉树a、采⽤顺序存储结构:⽤⼀维数组存储完全⼆叉树,结点的编号对于与结点的下标(如根为1,则根的左孩⼦为2*i=2*1=2,右孩⼦为2*i+1=2*1+1=2)添加描述b、采⽤链式存储结构:⼆叉链表:添加描述三叉链表:它的结点⽐⼆叉链表多⼀个指针域parent,⽤于执⾏结点的双亲,便于查找双亲结点添加描述两种存储结构⽐较:对于完全⼆叉树,采⽤顺序存储结构既能节省空间,⼜可利⽤数组元素的下标值确定结点在⼆叉树中的位置及结点之间的关系,但采⽤顺序存储结构存储⼀般⼆叉树容易造成空间浪费,链式结构可以克服这个缺点(3)⼆叉查找树:⼆叉查找树⼜称⼆叉排序树,或者是⼀课空⼆叉树,或者是具有如下特征的⼆叉树:a、若它的左⼦树不空,则左⼦树上所有结点的值均⼩于根结点的值b、若它的右⼦树不空,则右⼦树上所有结点的值均⼤于根结点的值c、它的左、右⼦树也分别是⼆叉查找树(4)平衡⼆叉树:平衡⼆叉查找树简称平衡⼆叉树,平衡⼆叉树或者是棵空树,或者是具有下列性质的⼆叉查找树:它的左⼦树和右⼦树都是平衡⼆叉树,且左⼦树和右⼦树的⾼度之差的绝对值不超过1添加描述平衡⼆叉树的失衡及调整主要可归纳为下列四种情况:LL型、RR型、LR型、RL型(5)树:树是含有n(n>=0)个结点的有限集合,在任意⼀棵⾮空树种: a、有且仅有⼀个特定的称为根的结点b、当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每⼀个集合本⾝⼜是⼀棵树,并且T1,T2,...,Tm称为根的⼦树(6)堆:堆是具有以下特性的完全⼆叉树,其所有⾮叶⼦结点均不⼤于(或不⼩于)其左右孩⼦结点。

线性表的类型定义、顺序表示和实现

线性表的类型定义、顺序表示和实现
– ①ai-1 和 ai逻辑关系发生变化 – ②需移动元素:
i=n 只删 an即可 1≤i≤n -1 将ai+1 ~an前移
23
bool deleteElem(SqList& L,int pos)
typedef int ElemType;
typedef char ElemType;
等;
②同一线性表中的数据元素必须具有相同的特性,属同一类 型;
③a2,关…系, ra是i-1,一a个i, a有i+1序, …偶,对an的)集,合a,i-1即领对先于于非ai,空表的示线了性数表据(元a1,素 之间的相邻关系,称ai-1是ai的直接前驱,ai是ai-1的直接后继 ;
6
2.1.3 操作举例
例:假设利用两个线性表La和Lb分别表示两 个集合A和B,求一个新的集合A=A∪B。
算法:
– ①取得Lb中的1个元素; – ②在La中查找这个元素; – ③若不存在:插入La中;若存在,取Lb中下一个
元素,重复 ①、②、③,直到取完Lb的每个元素 。
7
void unionList(SqList &la,SqList lb)
10
线性表的顺序存储结构示意图
存储地址
loc(a1) loc(a1)+ k
内存空间状态 逻辑地址
a1
1
a2
2



loc(a1)+ (i- 1)k
ai
i



loc(a1)+ (n- 1)k
an
n 空闲
顺序存储结构可以借助于高级程序设计语言中的一维数组来表示。
11
用C++语言描述的顺序表类型如下所示: sqlist.h

严蔚敏《数据结构》(C语言版)教材精讲(栈与队列)【圣才出品】

严蔚敏《数据结构》(C语言版)教材精讲(栈与队列)【圣才出品】
S.bottom=(ElemType *)realloc((S. STACKINCREMENT+STACK_SIZE) *sizeof(ElemType));/* 栈满,追加 存储空间 */
if(! S.bottom) return ERROR;
S.top=S.bottom+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top=e; S.top++; /* 栈顶指针加 1,e 成为新的栈顶 */ return OK; }
改是按后迕先出的原则迕行的。 进栈(push)
出栈(pop)
top
an ⋯⋯ ai ⋯⋯
图 3-1 顺序栈示意图
2.栈的抽象数据类型定义
ADT Stack {
数据对象:D={ ai|ai∈ElemSet,i=1,2,…,n,n≥0} 数据关系:R={<ai-1,ai>|ai-1,ai∈D,i=2,3,…,n} 基本操作:初始化、进栈、出栈、取栈顶元素等 }ADT Stack
1.栈的动态顺序存储表示 采用动态一维数组来存储栈。所谓动态,指的是栈的大小可以根据需要增加。 ①用 bottom 表示栈底指针,栈底固定丌变的;用 top 表示栈顶指针,栈顶则随着迕 栈和退栈操作而变化。 ②用 top=bottom 作为栈空的标记,每次 top 指向栈顶数组中的下一个存储位置。 ③结点迕栈:首先将数据元素保存到栈顶(top 所指的当前位置),然后执行 top 加 1, 使 top 指向栈顶的下一个存储位置; ④结点出栈:首先执行 top 减 1,使 top 指向栈顶元素的存储位置,然后将栈顶元素 取出。 动态堆栈变化示意图如图 3-2 所示。
基本操作的实现: ①栈的类型定义

数据结构与算法 c语言

数据结构与算法 c语言

数据结构与算法 c语言(一)数据结构数据结构是指程序中使用的数据存储和组织的方式,是存储和组织数据以便于进行有效访问和操作的形式。

它们描述如何组织、索引、检索和存储数据,可以以图形、列表、树或任何其他形式来实现。

根据它的功能,数据结构可以分为三类:存储结构,查找结构和排序结构。

1.存储结构:存储结构定义数据的存储形式,结构的类型有线性结构、非线性结构和特殊结构。

a)线性结构:线性结构是最常用的存储结构,常见的线性结构有数组、线性表和栈。

b)非线性结构:非线性结构是存储数据的不规则结构,常用的非线性结构有森林、图、哈希表和布局。

c)特殊结构:特殊结构是一种特殊的数据结构,代表着不同的操作对象。

例如,编译器存储着源程序的语法树,在设计数据库时,系统存储着索引树以及索引文件。

2.查找结构:查找结构包括线性查找和二分查找,前者将数据成员与关键字一一比较,后者使用二叉树技术,在减少比较次数的同时,使得查找效率大大提高。

3.排序结构:排序结构按照一定的规则对存储在某个存储结构中的数据进行排序,用于快速查找数据。

常用的排序算法有插入排序、合并排序、快速排序等。

总之,数据结构可以视为数据的容器,使用不同的数据结构可以解决不同的问题,提高系统的效率。

(二)算法算法是一种排列和组合的解决问题的过程。

它使用一组定义明确的步骤,按照该步骤来执行,最终解决问题。

一般来说,算法分为三种类型:贪心算法、动态规划和分治法。

1.贪心算法:贪心算法通过采用试探性选择来求解问题,它从不考虑过去的结果,而是假设采用当前最好的结果,从而得到最优解。

如择优法、多项式时间的算法都属于贪心算法。

2.动态规划:动态规划是求解决策过程最优化的数学术语,它结合搜索技术,用最优方式选择最佳决策。

常见的动态规划算法应用有最小路径求解,最优工作调度等。

3.分治法:分治法是算法设计中比较常用的思想,它的思想很简单,就是将问题分解成多个子问题,分别解决,最后合并解决结果,得到整体的问题的最优解。

数据结构(C语言版)(第2版)课后习题答案

数据结构(C语言版)(第2版)课后习题答案

数据结构(C语言版)(第2版)课后习题答案李冬梅2015.3目录第1章绪论 (1)第2章线性表 (5)第3章栈和队列 (13)第4章串、数组和广义表 (26)第5章树和二叉树 (33)第6章图 (42)第7章查找 (54)第8章排序 (65)第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。

答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。

如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。

数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。

在有些情况下,数据元素也称为元素、结点、记录等。

数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。

数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。

例如,学生基本信息表中的学号、姓名、性别等都是数据项。

数据对象:是性质相同的数据元素的集合,是数据的一个子集。

例如:整数数据对象是集合N={0,±1,±2,…},字母字符数据对象是集合C={‘A’,‘B’,…,‘Z’,‘a’,‘b’,…,‘z’},学生基本信息表也可是一个数据对象。

数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。

换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。

逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。

因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。

存储结构:数据对象在计算机中的存储表示,也称为物理结构。

抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。

具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。

2.1线性表概念

2.1线性表概念

线性表Content线性表的基本概念1线性表的顺序存储结构2线性表的链式存储结构3线性表的基本概念数据结构包括三个方面逻辑结构存储结构运算(a)集合结构(b)线性结构(c)树形结构(d)图结构四种基本的结构关系线性表的定义线性表是零个或多个数据元素构成的线性序列,记为(a0,a1,…,a n-1)。

线性表中的数据元素个数n称为线性表的长度。

当n=0 时,此线性表为空表。

设线性表(a0,a1,…a i-1,a i,a i+1,… a n-1),其中a i-1是a i的直接前驱a i+1是a i的直接后继a0没有直接前驱a n-1没有直接后继除a0和a n-1外,其他元素有且仅有一个直接前驱和一个直接后继学号姓名性别964501王小红女964502林悦女964503陈菁菁女964504张可可男1.字母表(A,B,C……Z )线性表举例2.学生信息表线性表的抽象数据类型(描述规范)ADT List{数据:零个或多个数据元素构成的线性序列(a0, a1, …, a n−1)。

数据元素之间的关系是一对一关系。

运算:Init(L):初始化运算。

构造一个空的线性表L,若初始化成功,则返回OK,否则返回ERROR。

Destroy(L):撤销运算。

判断线性表L 是否存在,若已存在,则撤销线性表L;否则,返回ERROR。

IsEmpty(L):判空运算。

判断线性表L 是否为空,若为空,则返回OK;否则返回ERROR。

Length(L):求长度运算。

若线性表L 已存在,返回线性表L 的元素个数;否则返回ERROR。

;否则,返回ERROR。

Find(L,i):查找运算。

若线性表L 已存在且0≤i≤n-1,则返回元素aiInsert(L,i, x):插入运算。

若线性表L 已存在且-1≤i≤n-1,则在元素ai之后插入新元素x,插入成功后返回OK,否则返回ERROR。

)线性表的抽象数据类型(描述规范,删除成功后返回OK,否则Delete(L,i):删除运算。

线性表_精品文档

线性表什么是线性表?线性表是一种常见的数据结构,它由一系列具有相同数据类型的元素组成。

线性表中的元素之间存在着一对一的线性关系,即每个元素都有唯一的直接前驱和直接后继(除了第一个元素没有直接前驱和最后一个元素没有直接后继)。

线性表可以用来存储一组有序的数据,例如整数、浮点数、字符等等。

它可以通过下标来访问元素,支持插入、删除和查找操作。

线性表的分类线性表可以分为两种基本形式:顺序表和链表。

顺序表顺序表是将线性表的元素按照顺序依次存储在一块连续的存储空间中。

在顺序表中,按照元素插入顺序分为静态顺序表和动态顺序表。

静态顺序表静态顺序表是指事先申请好固定大小的存储空间,用于存储线性表的元素。

静态顺序表的大小在编译时确定,无法动态调整。

当静态顺序表已满时,如果需要插入新的元素,就无法继续插入,需要进行额外的处理。

动态顺序表动态顺序表是指不事先申请固定大小的存储空间,而在需要时进行动态扩容和缩容的顺序表。

动态顺序表的大小可以根据需要动态调整,使得线性表可以动态增长或减少。

链表链表是一种通过指针将线性表的元素链接在一起的数据结构。

链表中的每个元素都包含一个指针,指向下一个元素。

链表的存储空间可以是连续的,也可以是不连续的。

单链表单链表是链表的基本形式。

每个节点包含数据域和指针域,数据域用于存储元素的值,指针域用于指向下一个元素。

链表的头节点没有前驱节点,尾节点没有后继节点。

双链表双链表是在单链表的基础上进行扩展的。

每个节点除了有指向下一个元素的指针,还有指向前一个元素的指针。

双链表可以支持双向遍历和双向操作,但相应地增加了额外的指针域,占用更多的存储空间。

线性表的操作线性表的常用操作包括插入、删除、查找、遍历等。

插入插入操作可以在线性表的指定位置插入一个新的元素。

插入元素时,需要移动后续元素的位置来腾出空间,并调整相应的指针。

插入操作的时间复杂度为O(n)。

删除删除操作可以删除线性表中指定位置的元素。

删除元素时,需要调整前后元素的指针,使得元素之间重新链接。

《数据结构》课程课件第二章线性表


Step2:数据域赋值
插入后: Step3:插入(连接)
X q
(1)式和(2)式的顺序颠倒,可以吗?
4、插入元素(在第i个元素之前插入元素e)
为什么时间复杂度不再是O(1)?
第i-1个元素
第i个元素
p
s
新插入元素
5、删除p所指元素的后继元素
P
删除前:
P->next P->next->next
删除:
五、线性表ADT的应用举例
Void mergelist(list La,list Lb,list &Lc)
{ //已知线性表La和Lb中的数据元素按值非递减排列
//归并La和Lb得到新的线性表Lc,Lc中的元素也按值非递减排列
例: 将两个各有n个元素的有序表归并成一个有序表, 其最小的比较次数是( )。 A、n B、2n-1 C、2n D、n-1
三、线性表的ADT
四、线性表的分类
五、线性表ADT的应用举例
例1:已知有线性表L,要求删除所有X的出现
五、线性表ADT的应用举例
例2: 已知有两个分别有序的线性表(从小到大),要 求合并两个线性表,且合并后仍然有序。——归并 方法1: 合并,再排序O((m+n)2)
方法2: 归并,利用分别有序的特点O((m+n))
二、线性表上常见的运算
8、删除 Delete(L,i):删除线性表的第i个元素 删除前 a1 a2 … ai-1 ai ai+1 … an 删除后 a1 a2 … ai-1 ai+1 … an 9、判断是否为空 Empty(L):线性表空,则返回TRUE, 否则FALSE 10、输出线性表 Print(L):输出线性表的各个元素 11、其它操作 复制、分解、合并、分类等

数据结构C语言版 线性表的单链表存储结构表示和实现

#include 〈stdio.h>#include <malloc。

h>#include 〈stdlib.h>/*数据结构C语言版线性表的单链表存储结构表示和实现P28—31编译环境:Dev-C++ 4。

9。

9。

2日期:2011年2月10日*/typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data; //数据域struct LNode *next;//指针域}LNode, *LinkList;// typedef struct LNode *LinkList;// 另一种定义LinkList的方法// 构造一个空的线性表Lint InitList(LinkList *L){/*产生头结点L,并使L指向此头结点,头节点的数据域为空,不放数据的。

void *malloc(size_t)这里对返回值进行强制类型转换了,返回值是指向空类型的指针类型.*/(*L)= (LinkList)malloc(sizeof(struct LNode) );if( !(*L))exit(0);// 存储分配失败(*L)-〉next = NULL;// 指针域为空return 1;}// 销毁线性表L,将包括头结点在内的所有元素释放其存储空间。

int DestroyList(LinkList *L){LinkList q;// 由于单链表的每一个元素是单独分配的,所以要一个一个的进行释放while(*L ){q = (*L)—〉next;free(*L );//释放*L = q;}return 1;}/*将L重置为空表,即将链表中除头结点外的所有元素释放其存储空间,但是将头结点指针域置空,这和销毁有区别哦。

不改变L,所以不需要用指针。

*/int ClearList( LinkList L ){LinkList p,q;p = L—〉next;// p指向第一个结点while( p ) // 没到表尾则继续循环{q = p—>next;free( p );//释放空间p = q;}L—>next = NULL; // 头结点指针域为空,链表成了一个空表return 1;}// 若L为空表(根据头结点L—〉next来判断,为空则是空表),则返回1,// 否则返回0.int ListEmpty(LinkList L){if(L—>next ) // 非空return 0;elsereturn 1;}// 返回L中数据元素个数。

数据结构(C语言)第一章


(4)输入
一个算法有零个或多个输入,这些输入取自于
某个特定的对象集合。
(5)输出
一个算法有一个或多个输出,这些输出是同输
入有着某些特定关系的量。 注意: 算法和程序是有区别的,即程序未必能满足有穷性。 本教材使用类C语言描述算法的,类C和标准C语言是有区 别的,同时,算法着重于思想的描述,可能会省略许多细节。 不要把算法看成程序,切忌将算法中的相应函数和数据类 型直接照搬到程序中。
19
例:编制一个事务管理的程序,管理学校科学研究课题小 组的各项事务,则首先要为程序的操作对象——课题小 组设计一个数据结构。 假设每个小组由一位教师、一至三名研究生及一至 六名本科生组成,小组成员之间的关系是:教师指导研 究生,而由每位研究生指导一至两名本科生。则可以如 下定义数据结构: Group = (P,R) 其中: P = {T,G1,…,Gn,S11…Snm} 1<=n<=3,1<=m<=2, R = {R1, R2} R1 = {<T, Gi> | 1<=i<=n, 1<=n<=3 } R2 = {<Gi, Sij> | 1<=i<=n, 1<=j<=m, 1<=n<=3, 1<=m<=2}
种或多种特定关系的数据元素的集合。
数据结构主要指逻辑结构和物理结构。
17
5. 逻辑结构:数据元素之间的逻辑关系。 根据数据元素之间的逻辑结构可将数据结构分为四类:
集合 ——结构中的数据元素除了同属于一种类型外,别无其 它关系。 线性结构——数据元素之间存在一对一的关系。如线性表、 栈、队列。 树形结构——数据元素之间存在一对多的关系。如树。 图状结构——数据元素之间存在多对多的关系,如图。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
i
数据域:元素本身信息 指针域:指示直接后继的存储位置
数据域 指针域
例 线性表 (ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG) 存储地址 头指针 H 31 1 7 13 19 25 31 37 43 阿珂 方怡 双儿 芙蓉XX 曾柔 苏荃 沐剑屏 建宁公主 43 13 1
n-1
an
n
剩 余 空 间
M-1
数据元素不是简单类型时,可定义结构体数组
V数组下标 0 1
内存 a1 a2
元素序号
1 2
n-1
an
n
#define LIST_INIT_SIZE 100 #define LIST_INCREMENT 10 Typedef struct{ Elemtype *Elem; int length; int listsize ; }SqList; SqList L;
§2.2 线性表的顺序存储结构
顺序表:
定义:用一组地址连续的存储单元存放一个线性表叫~ 元素地址计算方法:
LOC(ai)=LOC(a1)+(i-1)*L LOC(ai+1)=LOC(ai)+L 其中: L—一个元素占用的存储单元个数 LOC(ai)—线性表第i个元素的地址
特点:
M-1 动态申请和释放内存 L.Elem = (ElemType *)malloc(M *sizeof(ElemType)); free(L.Elem );
插入
定义:线性表的插入是指在第I(1i n+1)个元素 之前插入一个新的数据元素x,使长度为n的线性表
a
a
1
1
, a 2 , , ai 1 , ai , a n
}
// union
例 2-2 两个有序的数组合并为一个有序的数组
思路:设两个指针i,j分别指向LA和LB中的某个元素a和b, 则插入到LC中的某个元素c为 c = a 当a<=b时 b 当a > b时
void MergeList(List La, List Lb, List &Lc) {/ InitList(Lc); // 构造空的线性表 Lc i = j = 1; k = 0; La_len = ListLength(La); Lb_len = ListLength(Lb); while ((i <= La_len) && (j <= Lb_len)) { GetElem(La, i, ai); GetElem(Lb, j, bj); if (ai <= bj) { else { ListInsert(Lc, ++k, ai); ++i; ListInsert(Lc, ++k, bj); }
V数组下标
0 1
内存 元素序号
a1 a2 1 2
V数组下标 0
内存 元素序号 a1
1 2
1
a2
i-1 i
ai ai+1
i
1
i-1 i
ai+1 ai+2
i i+1
i+1
2
N-I
n-1 n
an
n n+1
n-2
an
n-1
n-1
Hale Waihona Puke n算法Status ListDelete_sq(SqList &L, int I, elemType & e) { if ( I < 1 || I >L.length) return error; //删除位置不合法 p = & (L.elem[I]; //移动元素(I+1)的起始位置 e = *p; q = L.elem + L.length –1; //表尾元素的位置 for (p; p <= q; p ++) *(p-1) = *p; //元素的移动 L.length--; return OK; }
{称 n 为线性表的表长; 称 n=0 时的线性表为空表。}
数据关系: R1={ <ai-1 ,ai >|ai-1 ,ai∈D, i=2,...,n }
{设线性表为 (a1,a2, . . . ,ai,. . . ,an), 称 i 为 ai 在线性表中的位。} 基本操作:
InitList( &L ) DestroyList( &L ) ClearList(&L) ListInsert(&L, i, e) ListDelete(&L, i, &e) 加工型操作
++j; }
}
while (i<=La_len) // 若 La 不空 {GetElem(La, i++, ai); ListInsert(Lc, ++k, ai); } while (j<=Lb_len) // 若 Lb 不空 {GetElem(Lb, j++, bj); ListInsert(Lc, ++k, bj);} } // merge_list
操作步骤:
1.从线性表LB中依次察看每个数据元素;
GetElem(LB, i)→e
2.依值在线性表LA中进行查访; LocateElem(LA, e, equal( ))
3.若不存在,则插入之。 ListInsert(LA, n+1, e)
void union(List &La, List Lb) { La_len = ListLength(La); Lb_len = ListLength(Lb); for (i = 1; i <= Lb_len; i++) { GetElem(Lb, i, e); // 取Lb中第i个数据元素赋给e if (!LocateElem(La, e, equal( )) ) ListInsert(La, ++La_len, e); // La中不存在和 e 相同的数据元素,则插入之 } // 求线性表的长度
ListEmpty(L) ListLength(L) PriorElem(L, cur_e, &pre_e) NextElem(L, cur_e, &next_e) GetElem(L, i, &e ) LocateElem( L, e, compare( )) ListTraverse(L, visit( )) 引用型操作
实现逻辑上相邻—物理地址相邻 实现随机存取
实现:可用C语言的一维数组实现
V数组下标 0 1
内存 a1 a2
元素序号 1 2
typedef int ElemType; #define M 1000 ElemType data[M]; 例 typedef struct card { int num; char name[20]; char author[10]; char publisher[30]; float price; }ElemType; ElemType library[M];
} ADT List
例 2-1
假设:有两个集合 A 和 B 分别用
两个线性表 LA 和 LB 表示,即:
线性表中的数据元素即为集合中的
成员。 现要求一个新的集合A=A∪B。
上述问题可演绎为:
要求对线性表作如下操作:
扩大线性表 LA,将存在于线性表 LB 中而不存在于线性表 LA 中的
数据元素插入到线性表 LA 中去。
算法时间复杂度T(n)
设Pi是在第i个元素之前插入一个元素的概率,则在长度为n 的线性表中插入一个元素时,所需移动的元素次数的平均次 数为:
Eis
P (n i 1)
i 1 i
n 1
若认为Pi
1 n 1
1 n 1 n 则Eis ( n i 1) n 1 i 1 2 T n O n
本章内容
§线性表的抽象数据类型定义 §线性表的存储结构 §线性表的应用
§2.1 线性表的类型定义
定义:一个线性表是n个数据元素的有限序列
a
1
, a2, , ai , an
姓名 柯镇恶 朱聪 …… 年龄 38 31 ……
例 英文字母表(A,B,C,…..Z)是一个线性表

编号 001 002 ……
N
插入位置的合理? T
足够的存储空间?
N 重新分配存储空间
T
报错
元素移动 元素插入,打印
ListInsert结束
算法
Status ListInsert_sq(SqList &L, int I, ElemType e)
{ if ( I < 1 || I > L.length +1 ) return error; //插入位置不合法 if (L.length >= L.ListSize) //存储空间不够用,重新分配 { sq = (ElemType *) realloc (L.elem, (L.ListSize + Listincrement) * sizeof (ElemType)); if (!sq) exit (overflow); L.elem = sq; //若分配成功 L.ListSize += Listincrement; } p = & L.elem[L.length – 1] ; //表尾位置 &(L.elem[I-1]) q= ; //新插入的元素的位置 for (p; p >= q; --p) *(p+1) = *p; //元素的移动 *q = e; //元素插入 L.length ++; Return OK; }
相关文档
最新文档