当前位置:文档之家› 数据结构第2章 线性表 教案

数据结构第2章 线性表 教案

第2章线性表本章主要内容:1、线性表的概念、特点、及其基本操作定义2、线性表的顺序存储结构及其算法实现3、线性表的链式存储结构及其算法实现4、循环链表及其线性表的应用本章重点难点:1、线性表的存储结构及算法实现。

2、链式存储结构及算法实现。

3、循环链表2.1 线性表的定义和基本操作2.1.1 线性表的定义及特点1.线性表的定义线性表是由n(n≥0)个类型相同的数据元素组成的有限序列。

n表示线性表中数据元素的个数,称为线性表的长度(简称表长)。

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

线性表的逻辑结构通常用数学中的向量形式表示:L=( a1,a2,...,ai-1,ai,ai+1,...,an) 或者L=( a0,a1,...,ai-1,ai,ai+1,...,an-1)其中:L为线性表名称,习惯用大写书写;ai为组成该线性表的数据元素,元素的数据类型可以是可以表示出的任何类型。

例 1:分析下列线性表的数据类型:La=(34,89,765,12,90,-34,22);Lb=(January, February,March,April,May,June,July,August,September,October,November,December,World, China,Welcome);Lc=(stu1,stu2,...,stu50) ;其中,数据元素stui的数据类型为:struct student{char Num; //学号char *name; //姓名};2、线性表的特点。

除第一个元素外,每个元素有且仅有唯一一个直接前驱,第一个元素无直接前驱,除最后一个元素外,每个元素有且仅有唯一一个直接后继,最后一个元素无直接后继。

1-1这种次序描述了元素之间的 1 对 1关系。

此外,我们所研究的线性表的元素个数是有限的,各元素的数据类型是相同德,且数据元素可以是任意类型。

2.1.2、线性表的基本操作(1)初始化线性表L InitList(L)(2)清空线性表L ClearList(L)(3)求线性表L的长度 ListLength(L)(4)判断线性表L是否为空 IsEmpty(L)(5)获取线性表L中的某个数据元素内容 GetElem(L,i,e)(6)查找值为e的数据元素 LocateELem(L,e)(7)返回线性表L中e的直接前驱元素 PriorElem(L,e)(8)返回线性表L中e的直接后继元素 NextElem(L,e)(9)在线性表L中插入一个数据元素 ListInsert(L,i,e)(10)删除线性表L中第i个数据元素 ListDelete(L,i,e)2. 2 线性表的顺序存储结构与操作算法实现2.2.1 线性表的顺序存储结构定义及其特点1、线性表的顺序存储结构(顺序表)线性表的顺序存储结构是指用一组连续的存储单元依次存储线性表中的每个数据元素。

如图2-1所示:图 2-1 顺序表的存储相邻两个数据元素的存储位置计算公式:LOC(a i)=LOC(a i-1)+C (2-1)线性表中任意一个数据元素的存储位置的计算公式为:LOC(a i)=LOC(a1)+(i-1)*C (2-2)或者:LOC(a i)=LOC(a0)+i*C (2-3)其中,C为每个数据元素所占据的存储单元数目。

2、顺序存储结构的特点优点:(1) 一致性。

在顺序表中,利用数据元素的存储位置相邻,表示线性表中数据元素之间的相邻前后关系,逻辑结构与存储结构(物理结构)一致;(2)可随机访问性。

在访问顺序表时,可以利用公式(2-2),(2-3),可以快速地计算出任何一个数据元素的存储地址。

因此,访问每个数据元素所花费的时相等。

这种存取元素的方法被称为随机存取法,使用这种存取方法的存储结构被称为随机存储结构。

缺点:(1)插入、删除低效。

对插入、删除等操作效率较低,需要移动大量元素。

(2)不便于扩充。

要动态增加元素个数较困难。

顺序表示适合于数据元素个数稳定、较少进行插入和删除操作、频繁进行查询操作的场合。

3、顺序存储结构的定义#define LIST_MAX_LENGTH 100 //线性表的最大长度typedef struct {Elemtype elem[LIST_MAX_LENGTH]; //指向存放线性表中数据元素int length; //线性表的当前长度} SQLIST;2.2.2 线性表的典型操作算法的实现(1)初始化线性表Lviod InitList(SEQLIST *L){ L->length=0; //将当前线性表长度置0}(2)清空线性表Lvoid ClearList(SEQLIST *L){ L->length=0; //将线性表的长度置为0}上面的两个算法的具体操作都是一样的,但是含义却不一样。

初始化一个线性表,是给出一个初始状态:表中没有元素,所以表长为0。

而清空线性表是说表里面是否有元素我们不管,只要定义了表长为0,就肯定了表是空表。

前者是对一个表的初始状态的描述,后者是强行达到空表的操作。

(3)求线性表L的长度int GetLength(SEQLIST L){ return (L.length);}(4)判断线性表L是否为空int IsEmpty(SEQLIST L){ if (L.length==0) return TRUE;else return FALSE;}( 5)获取线性表L中的某个数据元素的内容int GetElem(SEQLIST L,int i,Elemtype *e){ if (i<1||i>L.length) return ERROR;//判断i值是否合理,若不合理,返回ERROR*e=L.elem[i-1];//数组中第i-1的单元存储着线性表中第i个数据元素的内容 return OK;}(6)在线性表L中查找值为e的数据元素int LocateELem(SEQLIST L,Elemtype e){ for (i=0;i< L.length;i++)if (L.elem[i]==e) return i+1;return 0;}(7)在线性表L中第i个数据元素之前插入数据元素eint ListInsert(SEQLIST *L,int i,Elemtype e){ if (L->length==LIST_MAX_LENGTH) return ERROR;//检查是否有剩余空间if (i<1||i>L->length+1) return ERROR; //检查i值是否合理for (j=L->length-1;j>=i-1;i++)//将线性表第i个元素之后的所有元素向后移动L.->elem[j+1]=L->elem[j];L->elem[i-1]=e; //将新元素的内容放入线性表的第i个位置,L->length++;return OK;}(8)将线性表L中第i个数据元素删除int ListDelete(SEQLIST *L,int i,Elemtype *e){ if (IsEmpty(L)) return ERROR; //检测线性表是否为空if (i<1||i>L->length) return ERROR; //检查i值是否合理*e=L->elem[i-1];//将欲删除的数据元素内容保留在e所指示的存储单元中for (j=i;j<=L->length-1;j++)//将线性表第i+1个元素之后的所有元素向前移动L->elem[j-1]=L->elem[j];L->length--;return OK;}2.2.3算法效率分析1 、查找算法如果线性表的长度为n ,在查找成功的前提下,被查找的元素e 线性表的第i (1≤i ≤n ),i 的值不同,比较元素的个数不同,所以,我们用平均比较次数(又称为平均查找长度)ASL 来说明算法的效率:ASL=∑=ni i i C P 1。

其中,P i 是被查找元素是第i 个元素的概率,C i 是查找到第i 个元素的比较次数,在等概率的前提下,P i =1/n ,C i =i,所以,平均查找长度为ASL = (1+2+…+n)/n=(n+1)/2。

2、 插入算法顺序表的插入算法快慢主要通过元素的移动次数来决定,插入的位置不同,移动的元素的个数也不同,因此我们用平均移动元素个数来描述。

如果被插入元素的的插入位置为i (1≤i ≤n+1),则移动的元素个数为(n+1-i ),在插入位置等概率的情形下,平均移动元素个数为(∑+=-+111n n i i )/(n+1)=n/2。

3、 删除算法的平均移动元素的个数为(n-1)/ 2和插入算法一样,删除算法的时间复杂度也是由元素移动的次数来决定的,我们任然用平均移动次数来描述。

如果被删除元素为线性表的第i (1≤i ≤n )个元素,则移动的元素个数为n-i ,在删除元素位置等概率的前提下,平均移动元素个数为(∑=-ni i 1n )/n=(n-1)/2。

所以,查找算法、插入算法和删除算法的时间复杂度都是用O 表示都是O(n),即n 的线性函数。

4、 其他算法的时间复杂度都是 O(1)。

2. 3 线性表的链式存储结构线性表顺序存储结构的缺点是在做插入或删除元素的操作时,会产生大量的数据元素移动;对于长度变化较大的线性表,要一次性地分配足够的存储空间,但这些空间常常又得不到充分的利用;线性表的容量难以扩充。

2.3.1 线性表的链式存储结构及特点1、线性表的链式存储结构:指用一组任意的存储单元(可以连续,也可以不连续)存储线性表中的数据元素。

为了反映数据元素之间的逻辑关系,对于每个数据元素不仅要表示它的具体内容,还要附加一个表示它的直接后继元素存储位置的信息。

假设有一个线性表(a 1,a 2,...,a n ),可用图2-2所示的形式存储:图2-2 链表的存储2、链式存储结构的特点优点:(1)插入、删除操作方便性。

不需移动元素,数据个数可动态增长。

(2)不连续占用存储空间。

缺点:(1)不一致性。

线性表中的数据元素在存储单元中的存放顺序与逻辑顺序不一定一致;(2)只能顺序访问性。

在对线性表操作时,只能通过头指针进入链表,并通过每个结点的指针域向后扫描其余结点,这样就会造成寻找第一个结点和寻找最后一个结点所花费的时间不等,具有这种特点的存取方式被称为顺序存取方式。

链式存储结构适合于数据各是动态变化、插入、删除频繁的场合。

3、链式存储结构的定义在C语言中,实现线性表的链式存储结构的类型定义typedef strcut Node{ //结点类型Elemtype elem;struct Node *next;} Node, *LINKLIST;2.3.2 链表的典型操作的算法实现通常我们采用带有头结点的单链表来存储线性表,初始的时候头结点的next 域为空。

相关主题