第2章 线性表2
数据结构习题及答案与实验指导(线性表)2
第2章线性表线性表是一种最基本、最常用的数据结构,它有两种存储结构——顺序表和链表。
本章主要介绍线性表的定义、表示和基本运算的实现。
重点讨论了线性表的存储结构,以及在顺序、链式两种存储结构上基本运算的实现。
重点提示:●线性表的逻辑结构特征●线性表的顺序存储和链式存储两种存储结构的特点●在两种存储结构下基本操作的实现2-1 重点难点指导2-1-1 相关术语1.线性表线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,通常记为:(a1,a2,…,a n),其中n为表长,n=0时称为空表。
要点:一种逻辑结构,其数据元素属于相同数据类型,之间的关系是线性关系。
2.顺序表顺序存储的线性表。
要点:按线性表中的元素的逻辑顺序依次存放在地址连续的存储单元里,其存储特点:用物理上的相邻实现逻辑上的相邻。
3.链表用链表存储的线性表。
要点:链表是通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,对每个结点的地址是否连续没有要求。
4.单链表每个结点除了数据域外还有一个指向其后继的指针域。
要点:通常将每个元素的值和其直接后继的地址作为一个结点,通过每个结点中指向后继结点的指针表示线性表的逻辑结构。
5.头指针要点:头指针是一个指针变量,里面存放的是链表中首结点的地址,并以此来标识一个链表。
如链表H,链表L等,表示链表中第一个结点的地址存放在指针变量H、L中。
通常用头指针来惟一标识一个链表。
6.头结点要点:附加在第一个元素结点之前的一个结点,头指针指向头结点。
当该链表表示一个非空的线性表时,头结点的指针域指向第一个元素结点;为空表时,该指针域为空。
7.头结点的作用要点:其作用有两个,一是使对空表和非空表的处理得到统一;二是在链表的第一个位置上的操作和在其他位置上的操作一致,无需特殊处理。
2-1-2 线性表的顺序存储1.顺序表顺序存储的线性表称为顺序表。
其特点是:用一组地址连续的存储单元来依次存放线性表的数据元素,因此数据元素的逻辑顺序和物理次序一致(这是顺序存储的核心所在)。
数据结构第二章:线性表
实现:可用C 实现:可用C语言的一维数组实现
6
V数组下标 0 1
内存 a1 a2
元素序号 1 2
typedef int DATATYPE; #define M 1000 DATATYPE data[M]; 例 typedef struct card { int num; char name[20]; char author[10]; char publisher[30]; float price; }DATATYPE; DATATYPE library[M];
4
{加工型操作 加工型操作} 加工型操作
ClearList( &L ) 初始条件:线性表 L 已存在。 操作结果:将 L 重置为空表。 PutElem( &L, i, &e ) 初始条件:线性表L已存在,1≤i≤LengthList(L)。 操作结果:L 中第 i 个元素赋值同 e 的值 ListInsert( &L, i, e ) 初始条件:线性表 L 已存在,1≤i≤LengthList(L)+1。 操作结果:在 L 的第 i 个元素之前插入新的元素 e,L 的长度增1。 ListDelete( &L, i, &e ) 初始条件:线性表 L 已存在且非空,1≤i≤LengthList(L)。 操作结果:删除 L 的第 i 个元素,并用 e 返回其值,L 的长度减1。 }ADT LIST
3
PriorElem( PriorElem L, cur_e, &pre_e ) 初始条件:线性表 L 已存在。 操作结果:若 cur_e 是 L 中的数据元素,则用 pre_e 返回 它的前驱,否则操作失败,pre_e 无定义。 NextElem( NextElem L, cur_e, &next_e ) 初始条件:线性表 L 已存在。 操作结果:若 cur_e 是 L 中的数据元素,则用 next_e 返 回它的后继,否则操作失败,next_e 无定义。 GetElem( GetElem L, i, &e ) 初始条件:线性表 L 已存在,1≤i≤LengthList(L)。 操作结果:用 e 返回 L 中第 i 个元素的值。 LocateElem( LocateElem L, e, compare( ) ) 初始条件:线性表 L 已存在,compare( ) 是元素判定函数。 操作结果:返回 L 中第1个与 e 满足关系 compare( ) 的元 素的位序。若这样的元素不存在,则返回值为0。 ListTraverse(L, visit( )) ListTraverse 初始条件:线性表 L 已存在,visit( ) 为元素的访问函数。 操作结果:依次对 L 的每个元素调用函数 visit( )。 一旦 visit( ) 失败,则操作失败。
《数据结构与算法(C++语言版)》第2章 线性表
数据结构与算法 (C++语言版)
第2章 线性表
线性表的类型定义
• 基本概念 • 线性表是由n(n≥0)个类型相同的数据元素组成的有限序 列,通常表示为L=(a1, …, ai–1, ai, ai+1, …, an)。其中,L为线 性表名称,ai为组成该线性表的数据元素,ai–1领先于ai,ai 领先于ai+1,称ai–1是ai的直接前驱元素,ai+1是ai的直接后继 元素。当i=1, 2, …, n–1时,ai有且仅有一个直接后继;当 i=2, 3, …, n时,ai有且仅有一个直接前驱。 • 线性表的长度就是线性表中元素的个数n(n≥0)。当n=0时, 称为空表。在非空表中的每个数据元素都有一个确定的位 置,如a1是第一个数据元素,an是最后一个数据元素,ai是 第i个数据元素。称i为数据元素ai在线性表中的位序。
线性表的类型定义
Prev_Elem(L, cur_e, &pre_e) //返回当前元素的前一个元素值 输入:线性表L。 输出:若cur_e是线性表L的数据元素,且不是第一个,则用 pre_e返回它的直接前驱元 素;否则操作失败,pre_e无定义。 Next_Elem(L, cur_e, &next_e) //返回当前元素的后一个元素值 输入:线性表L。 输出:若cur_e是线性表L的数据元素,且不是最后一个,则用 next_e返回它的直接后继元素;否则操作失败,next_e无定 义。
算法与数据结构第2章 线性表
利用已有基本运算求解问题 例2.1 假设有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即线性表中的数据元素即为集合中的成员。编写一 个算法求一个新的集合C=A∪B,即将两个集合的并集放在线 性表LC中。 解题思路: LC LA LC LB中不在LA中的元素
void unionList(List LA,List LB,List &LC)
该运算返回L中第 i(1≤i≤ListLength(L))个元素的值,存放在e中。
e=L->data[i-1];
return 1; } 本算法的时间复杂度为O(1)。
(7) 按元素值查找LocateElem(L,e) 该运算顺序查找第1个值域与e相等的元素的位序。若这样的元 素不存在,则返回值为0。 int LocateElem(SqList *L, ElemType e) { int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) else } return i+1; return 0;
{ int lena,lenb,lenc,i; ElemType e; InitList(LC); lena=ListLength(LA); for (i=1;i<=lena;i++) //求线性表的长度
//将LA的所有元素插入到Lc中
{ GetElem(LA,i,e); ListInsert(LC,i,e);
0
返回到 sq Main:
???
main:
引用的作用 main() { SqList *sq; InitList(sq); op(sq);
数据结构课件第2章线性表
27
线性表的顺序存储结构适用于数据 元素不经常变动或只需在顺序存取设备 上做成批处理的场合。为了克服线性表 顺序存储结构的缺点,可采用线性表的 链式存储结构。
28
2.3 线性表的链式存储结构
线性表的链式存储表示 基本操作在单链表上的实现 循环链表 双向链表 线性表链式存储结构小结
2.3.1 线性表的链式存储表示 29
2.1.1 线性表的定义
6
一个线性表(linear_list)是 n(n≥0)个具有相同属性的数 据元素的有限序列,其中各元素有着依次相邻的逻辑关系。
线性表中数据元素的个数 n 称为线性表的长度。当 n = 0 时 该线性表称为空表。当 n > 0 时该线性表可以记为:
(a1,a2,a3,…,ai,…,an)
数据域 指针域
结点 data next
31
(2) 线性表的单链表存储结构
通过每个结点的指针域将线性表中 n 个结点按其逻辑顺序链 接在一起的结点序列称为链表,即为线性表 ( a1, a2, a3, …, ai, …, an ) 的链式存储结构。如果线性链表中的每个结点只有一个指针域, 则链表又称为线性链表或单链表 (linked list)。
17
(2) 算法编写
#define OK 1
#define ERROR 0
Int InsList ( SeqList *L, int i, ElemType e ) /*在顺序线性表 L 中第 i 个位置插入新的元素 e。*/ /* i 的合法值为 1≤i ≤L->last+2*/ {
int k; if ( i < 1) ||( i > L->last+2)) /*首先判断插入位置是否合法*/ { printf(“插入位置i值不合法”);
第二章线性表
;查询通讯录信息。
第2页
目录
目录 退出
第二章 线性表
struct TelRed {char name[20]; char tel[12]; }; struct TelRed TelBook[100]; int length; 结构体数组TelBook和表示通讯录长度length二者实际 上是作为通讯录的一部分出现的,将二者作为一个整体来 表示通讯录。
第21页
目录
目录 退出
第二章 线性表
算法思想:
1)检查 i 值是否超出所允许的范围 (1 i n + 1) ,若超出
,则进行“超出范围”错误处理; 2)将线性表的第 i 个元素和它后面的所有元素均后移一个 位置; 3)将新元素写入到空出的第 i 个位置上;
4)使线性表的长度增 1。
第22页
第10页
目录
目录 退出
第二章 线性表
③ DestroyList(&L) 初始条件:线性表L已存在。
操作结果:销毁线性表L。
④ ClearList(&L) 初始条件:线性表L已存在。 操作结果:将L置为空表。 ⑤ EmptyList(L) 初始条件:线性表L已存在。 操作结果:如果L为空表,则返回TRUE,否则返回FALSE。 ⑥ GetData(L,i,&a) 初始条件:表L存在,且1≤i≤ListLength(L)。 操作结果:用a返回线性表L中第i个数据元素的值。
2、有且仅有一个终端结点 an,它没有直接后继,而仅有 一个直
接前趋 an -1, an 叫表尾元素;
3、其余的内部结点 ai (2 i n -1) 都有且仅有一个直接 前趋 ai –1
和一个直接后继 ai +1。
吉林大学数据结构_第二章 线性表
如何找指定位置的结点?
• 与顺序表不同,单链表无法直接访问指定 位置的结点,而是需要从哨位结点开始, 沿着next指针逐个结点计数,直至到达指定 位置。
操作
• • • • 存取 查找 删除 插入
存取算法
算法Find(k.item) /*将链表中第k个结点的字段值赋给item*/ F1. [k合法?] IF (k<1) THEN (PRINT “存取位置不合法”. RETURN.) F2. [初始化] p←head. i ←0. F3. [找第k个结点] WHILE (p ≠NULL AND i<k) DO (p←next(p). i ←i+1.) IF p=NULL THEN (PRINT “无此结点”. RETURN. ) item←data(p). ▍ 存取算法的时间复杂性分析。P30
插入算法
算法Insert(k,item) /*在链表中第k个结点后插入字段值为item的结点*/ I1.[k合法?] IF (k<0) THEN (PRINT “插入不合法”. RETURN) I2.[初始化] p←head. i ←0. I3.[p指向第k个结点] WHILE (p ≠NULL AND i<k) DO (p←next(p). i ←i+1.) IF p=NULL THEN (PRINT “插入不合法”. RETURN. ) I4.[插入] s<= AVAIL. data(s) ←item. next(s) ←next(p). next(p) ←s. ▍
删除算法
算法Delete(k.item) /*删除链表中第k个结点并将其字段值赋给item*/ D1.[k合法?] IF (k<1) THEN (PRINT “删除不合法”. RETURN.) D2.[初始化] p←head. i ←0. D3.[找第k-1结点] WHILE (p ≠NULL AND i<k-1) DO (p←next(p). i ←i+1.) IF p=NULL THEN (PRINT “无此结点”. RETURN. ) D4.[删除] q ← next(p). next(p) ← next(q) . item←data(q). AVAIL<=q.▍
《数据结构》课程课件第二章线性表
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、其它操作 复制、分解、合并、分类等
第2-5章 线性结构
第二章线性表2-1 设有一个线性表(e0, e1, …, e n-2, e n-1)存放在一个一维数组A[arraySize]中的前n个数组元素位置。
请编写一个函数将这个线性表原地逆置,即将数组的前n个原址内容置换为(e n-1, e n-2, …, e1, e0)。
2-2 设有一个二维数组A[m][n],假设A[0][0]存放位置在644(10),A[2][2]存放位置在676,每个元素占一个空间,问A[3][3](10)存放在什么位置?脚注(10)表示用10进(10)制表示。
2-3 设有一个n n的对称矩阵A,如图(a)所示。
为了节约存储,可以只存对角线及对角线以上的元素,或者只存对角线或对角线以下的元素。
前者称为上三角矩阵,后者称为下三角矩阵。
我们把它们按行存放于一个一维数组B中,如图(b)和图(c)所示。
并称之为对称矩阵A的压缩存储方式。
试问:(1) 存放对称矩阵A上三角部分或下三角部分的一维数组B有多少元素?(2) 若在一维数组B中从0号位置开始存放,则如图(a)所示的对称矩阵中的任一元素a ij在只存上三角部分的情形下(图(b))应存于一维数组的什么下标位置?给出计算公式。
(3) 若在一维数组B中从0号位置开始存放,则如图(a)所示的对称矩阵中的任一元素a ij在只存下三角部分的情形下(图(c))应存于一维数组的什么下标位置?给出计算公式。
2-4 编写一个算法frequency,统计在一个输入字符串中各个不同字符出现的频度。
用适当的测试数据来验证这个算法。
2-5 利用顺序表的操作,实现以下的函数。
(1) 从顺序表中删除具有最小值的元素并由函数返回被删元素的值。
空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行。
(3) 向顺序表中第i个位置插入一个新的元素x。
如果i不合理则显示出错信息并退出运行。
(8) 从顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同。
2-6 字符串的替换操作replace ( String& s, String& t, String& v) 是指:若t是s的子串,则用串v替换串t在串s中的所有出现;若t不是s的子串,则串s不变。
第2章 线性表
【例2】巳知有两个按元素值递增有序的顺序表La和 Lb,设计一个算法将表La和表Lb的全部元素归并 为一个按元素值递增有序的顺序表Lc。
算法思路:用i扫描顺序表La,用j扫描顺序表Lb。 当表La和表Lb都未扫描完时,比较两者的当前元 素,将较小者插入表Lc的表尾,若两者的当前元 素相等,则将这两个元素依次插入表Lc的表尾。 最后,将尚为扫描完的顺序表的余下部分元素依 次插入表Lc的表尾。算法如下: void MergeList_Sq(SqList La, SqList Lb, SqList &Lc)
表中ai-1领先于ai,称ai-1是ai的直接前驱,ai+1是 ai的直接后继。
线性表的抽象数据类型定义 (参见教材)
返回本章目录
2.2 线性表的顺序存储结构
线性表的顺序存储是指在内存中用地址连续的一块存储空间 依次存放线性表的数据元素,用这种存储形式存储的线性表 称其为顺序表。 假设每个数据元素占d个存储单元,且将ai的存储地址表示为 Loc(ai),则有如下关系: Loc(ai)=Loc(a1)+(i-1)*d Loc(a1)是线性表的第一个数据元素a1的存储地址,通常 称作线性表的基地址。
【例1】 编写一算法,从顺序表中删除自第i个元素开 始的k个元素。 算法思路: 为保持顺序表的逻辑特性,需将i+k ~ n位 置的所有元素依次前移k个位置。算法如下:
int deleteK(Sqlist &sq,int i,int k)
{ if (i<1||k<1||i+k-1>sq.len) return 0; for (j=i+k-1;j<=sq.len-1;j++) sq.data[j-k]=sq.data[j]; sq.len-=k; return 1; }// deleteK
DSFA第2章
14
template<class T> bool SeqList<T>::Find(int i,T& x) const { if (i<0 || i>n-1) { cout<<"Out of Bounds"<<endl; return false; } x=elements[i]; return true; } 渐近时间复杂度:O(1)
渐近时间复杂度:O(n)
18
nHale Waihona Puke 1(3)删除操作 Delete(i): 删除元素ai。 删除它
前移n-i-1个元素
a0
0
… ai-1 ai ai+1 … … an-1 … …
… i-1 i i+1 i+2 … 删除操作 n-1 … maxLength-1
19
删除操作算法: template <class T> bool SeqList<T>::Delete(int i) { if ( !n ) { cout<<"UnderFlow"<<endl; return false; } if ( i<0 || i>n-1 ) { cout<<"Out Of Bounds"<<endl; return false; } for (int j=i+1;j<n;j++) elements[j-1]=elements[j]; n--; return true; }
4. 动态一维数组描述顺序表
class SeqList:public LinearList<T> { public: SeqList(int mSize); …… private: int maxLength; T *elements; //动态一维数组的指针 }
第2章演示
2.2 线性表的顺序表示和实现 一、顺序表 3.顺序表类型定义 注意: ①存放线性表结点的向量空间的大小MaxSize应仔细 选值,使其既能满足表结点的数目动态增加的需求, 又不致于预先定义过大而浪费存储空间。 ② 由于C语言中向量的下标从0开始,所以若L是 SqList类型的顺序表,则线性表的开始结点a1和终端 结点an分别存储在L.data[0]和L.data[L.length-1]中。 ③若L是SqList类型的指针变量,则a1和an分别存储在 L->data[0]和L->data[L->length-1]中。 ④顺序表的的特点是逻辑上相邻的结点其物理位置亦 相邻。
单链表 6、指针变量和结点变量
注意:指针变量p与结点变量*p的关系。 指针变量p的值是地址; 结点变量*p的值是结点内容。
单链表 6、指针变量和结点变量
说明: ①生成结点变量空间的标准函数 p=( Lnode *)malloc(sizeof(Lnode)); //函数malloc分配一个类型为Lnode的结点变量的 空间,并将其首地址放入指针变量p中 ②释放结点变量空间的标准函数 free(p);//释放p所指的结点变量空间
2.1 线性表的类型定义
2.1 线性表的类型定义 二、线性表的逻辑结构特征 对于非空的线性表: ① 有且仅有一个开始结点a1,没有直接前趋,有且 仅有一个直接后继a2; ② 有且仅有一个终结结点an,没有直接后继,有且 仅有一个直接前趋an-1; ③ 其余的内部结点ai(2≤i≤n-1)都有且仅有一个 直接前趋ai-1和一个直接后继ai+1。
单链表 6、指针变量和结点变量
说明: ③结点分量的访问 利用结点变量的名字*p访问结点分量 方法一:(*p).data和(*p).next 方法二:p-﹥data和p-﹥next
第2章 线性表
数。
第2章 线性表
2.2 线性表的顺序存储结构表示
图2-2所示为线性表在存储介质中顺序分配的情况。
第2章 线性表
逻辑地址 1 2 记录内容 a1 a2 存储地址 LOC(a ) 1 LOC(a )+k 1 内存状况 a1 a2
…
i
…
ai LOC(a )+(i-1)× k 1
…
ai
…
n
图2-2 线性表的顺序分配
第2章 线性表
2.3 线性表元素的操作
2.3.1 线性表元素插入操作 插入一个记录,对有序线性表结构的影响可以从以下 两个方面分析。
(1) 若插入记录关键字的值比表中所有的数据元素的
关键字值都大,那么只需在表后添加一个新记录元素,同 时使表的当前长度修正为n+1即可。
(2) 若插入记录的位置出现在线性表的中间,则情况
LOC(ai)=LOC(a1)+(i-1)×k
从以上的地址计算公式可知,只要已知线性表第 一个数据元素在内存中的存储地址,又知道每一个数 据元素所占存储单元的个数,就能计算出第i个数据元 素在内存中的位置。
第2章 线性表 例如,线性表中第一个数据元素在内存中的地址 LOC(a1)为1000,每一个数据元素占用2个存储单位,
名称“数据结构”的属性就不相同,它们分别为字符
型和数值型。
第2章 线性表 2.1.2 线性表的逻辑结构表示 在任何问题中,数据元素之间可以存在多种关系。 从数据结构的观点来看,重要的是数据元素之间的逻辑 关系。所谓逻辑关系,是指数据元素之间的关联方式或 称“邻接关系”。表2-1中数据的逻辑结构如图2-1(b)所 示,其中的圆圈称为结点。一个结点代表一个数据元素 (有时也把结点和数据元素当作同义词),结点之间的连 线代表逻辑关系,即相应数据元素之间的邻接关系。图 2-1(b)中的逻辑结构反映了表2-1中表格作为一个数据的 组织形式,这种组织形式就是数据元素(记录)“一个接 一个地排列”。
第二章线性表
65
865
姓名
学号
成绩
班级 机97性表
※线性表及运算 ※线性表的存储结构
2.1线性表及运算
线性表是n个元素的有限序列,它们之间的关 系可以排成一个线性序列:
a1,a2,…… ,ai,…… ,an
其中n称作表的长度,当n=0时,称作空表。
线性表的特点:
1.线性表中所有元素的性质相同。 2.除第一个和最后一个数据元素之外,其它数据元 素有且仅有一个前驱和一个后继。第一个数据元 素无前驱,最后一个数据元素无后继。
Status ListInsert_L(LinkList &L,int i, ElemType x){ p=L; j=0; while( p&&j<i-1)
P P
a a
b b
{p=p->next; ++j;}
if( ! p j>i-1) return ERROR;
s=(struct LNode *)malloc(sizeof(struct LNode)); s->data=x; s->next=p->next; p->next=s;
3.数据元素在表中的位置只取决于它自身的序号。
在线性表上常用的运算有:
初始化、求长度、取元素、定位、插 入及删除等。
2.2 线性表的存储结构
1.顺序存储结构
2.链式存储结构
2.1. 线性表的顺序存储结构 ,可用C语言中的一维数组来描述. #define LISTINITSIZE 100 //线性表存储空间的初始分配量
s=(struct LNode *)malloc(sizeof(struct LNode)); s->data=x; s->next=p->next; p->next=s;
第2章 线性表
MaxSize-1
说明:SqListClass<T>的模板类的一个对象L称为顺序 表对象L,也简称为顺序表L,其中主要有data、length数据 成员和相关的运算函数,通过L.data或L.length对数据成员进 行操作,后面的顺序栈、顺序队、顺序串等都采用相似的方 式。
(6)插入数据元素ListInsert(i,e) 该运算在线性表中逻辑序号为i的位臵上插入一个新元素 e。如图2.4所示是插入元素的示意图,由此看出,在一个线 性表中,可以在两端及中间任何位臵上插入一个新元素。
ቤተ መጻሕፍቲ ባይዱ
template <typename T> bool SqListClass<T>::ListInsert(int i, T e) //插入数据元素 { int j; if (i<1 || i>length+1) return false; //参数错误时返回false for (j=length;j>=i;j--) //将data[i-1]及后面元素后移一个位臵 data[j]=data[j-1]; data[i-1]=e; //插入元素e length++; //顺序表长度增1 return true; //成功插入返回true }
(5)按元素值查找LocateElem(e) 该运算顺序查找第一个值与e相等的元素的逻辑序号。若 顺序表中不存在这样的元素,则返回值为0。对应的算法如下:
template <typename T> int SqListClass<T>::LocateElem(T e) //按元素值查找其序号 { int i=0; while (i < length && data[i]!=e) i++; //查找元素e if (i>=length) return 0; //未找到时返回0 else return i+1; //找到后返回其逻辑序号 }
数据结构导论 第2章 线性表
线性表是一种线性结构,线性结构的特点是数据元 素之间是一种线性关系,数据元素“一个接一个的 排列”。 线性结构是n(n>=0)个结点的有穷序列。对于 n>0的线性结构表示成: (a1,a2,… ai-1,ai,ai+1,…an) a1称为起始结点 an称为终端结点 起始结点, 终端结点; 起始结点 终端结点 ai-1 称为 ai 的直接前趋 i+1 称为 ai 的直接后继 直接前趋,a 直接后继。 直接前趋 直接后继
4.查找(定位) locate(L,x): .查找(定位) :
依次将顺序表L中的每个元素与给定的值x进行比 较。若找到则返回其序号(下标+1),否则返回0。 int locate (sqlist L, datatype x) { int i; for ( i=0; i<st; i++) if (L.data[i]==x) return (i+1); return(0); }
void insert (sqlist *L, datatype x, int i ) { if (i<1 || i>L->last+1) error (“插入位置错误”); else if (L->last==maxsize) error (“溢出”); else { for (j=L->last-1; j>=i-1; j--) //往后移动元素 //往后移动元素 L->data[j+1]=L->data[j]; L->data[i-1]=x; //插入x L->last++; //修改表长 } }
常见的线性表的基本运算有以下几个: 常见的线性表的基本运算有以下几个:
数据结构-C语言描述(第二版)(耿国华)章 (2)
2.1 线性表的概念及运算 2.2 线性表的顺序存储 2.3 线性表的链式存储 2.4 一元多项式的表示及相加
第2章 线 性 表 2.1 线性表的概念及运算
2.1.1 线性表的逻辑结构 线性表是n个类型相同的数据元素的有限序列,数据元素之
间是一对一的关系,即每个数据元素最多有一个直接前驱和一 个直接后继,如图2.1所示。例如:英文字母表(A,B,…, Z)就是一个简单的线性表,表中的每一个英文字母是一个数据 元素,每个元素之间存在唯一的顺序关系,如在英文字母表字 母B的前面是字母A,而字母B的后面是字母C。在较为复杂的线 性表中,数据元素(data elements)可由若干数据项组成,如 学生成绩表中,每个学生及其各科成绩是一个数据元素,它由 学号、姓名、各科成绩及平均成绩等数据项(item组成,常被称 为一个记录(record) ,含有大量记录的线性表称为文件(file)。 数据对象(dataobject)是性质相同的数据元素集合。
第2章 线 性 表
假设线性表中有n个元素,每个元素占k个单元,第 一个元素的地址为loc(a1),则可以通过如下公式计算出第i 个元素的地址loc(a -i):
loc(ai) =loc(a1)+(i-1)×k 其中loc(a -2.2 顺序表存储示意图
第2章 线 性 表
操作前提: 1≤i≤ListLength(L)。
表L已存在且非空,
操作结果: 删除L的第i个数据元素, 并用e返回其值, L的长度减1。
} ADT LinearList
第2章 线 性 表 2.2 线性表的顺序存储
2.2.1 线性表的顺序存储结构
线性表的顺序存储是指用一组地址连续的存储单元依 次存储线性表中的各个元素,使得线性表中在逻辑结构 上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元 素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。 采用顺序存储结构的线性表通常称为顺序表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
∧
^
Pointer
^
New
25
CS&T Information Course
Head
∧
1
Alan
^
^
Pointer
^
New
26
CS&T Information Course
Head
∧
1
Alan
^
^ Pointer
New
27
CS&T Information Course
∧
1
Alan
^
2
Bob
^
Pointer
如何申请一个结点?
15
CS&T Information Course
单链表
单链表的结点结构:
data
next
typedef struct node {int data; s=(Lnode*)malloc(sizeof(Lnode)) struct node *next; }Lnode,*linklist; /* Lnode为结点类型,linklist为 … 指向结点的指针类型*/
数据结构(C版)
Beyond Technology
东软信息学院计算机系信息化课程
数据结构(C)
CS&T Information Course
复习
• 1.线性表顺序存储结构的特点(顺序表的概念)。 – 在用一组连续的存储空间依次存放线性表的数据元素,这种 存储方式叫做线性表的顺序存储结构,简称顺序表。 • 2.线性表顺序存储结构的优缺点。 – 优点 • 逻辑相邻,物理相邻 • 可随机存取任一元素 • 存储空间使用紧凑 – 缺点 • 插入、删除操作需要移动大量的元素 • 预先分配空间需按最大空间分配,利用不充分 • 表容量难以扩充
typedef struct node { int data;
/*定义了数据域,这里存储的是整型的数据*/
struct node *next;
/*定义了指针域*/
}Lnode,*linklist; /* Lnode为结点类型,linklist为指向结点的指针类型*/
单链表的结点结构:
data
next
请大家自己试着写出完整的算法
36
CS&T Information Course
Head ^
^
Pointer
^
New
对应语句: student *Head,*Pointer,*New;
37
CS&T Information Course
Head
∧
^ Pointer
^ New
对应语句:
Head=(student *)malloc(sizeof(student)); Head->next=NULL;
为了克服顺序表的缺点
2
CS&T Information Course
3.1 线性表的链式存储结构
用一组任意的存储单元存储线性表的数据 元素(这组存储单元可以是连续的,也可以是 不连续的),数据元素之间的逻辑关系借助指 示元素存储位置的指针来表示,这种存储方式 叫做线性表的链式存储结构,简称链表。
3
空表 first
∧
非空表
first
a1
a2
an ∧
19
CS&T Information Course
练习
• • • • • • 1.不带头结点的单链表head为空的判定条件() A.head==null B.head->next=null C.head->next==head D.head!=null 2.带头结点的的单链表head为空的判定条件() A.head==null B.head->next=null C.head->next==head D.head!=null
^
Pointer
New
31
CS&T Information Course
Head
∧
1
Alan
2
Bob
3
Tom
^
Pointer
New
32
CS&T Information Course
Head
∧
1
Alan
2
Bob
3
Tom
^
Pointer
New
33
CS&T Information Course
Head
6
CS&T Information Course
3.2 链式存储结构特点
每个数据元素ai,除存储本身信息外,还需存储其 直接后继的信息 结点
数据域:元素本身信息 指针域:指示直接后继的存储位置
数据域 指针域
7
CS&T Information Course
链表分类
单链表 双向链表 循环链表
20
CS&T Information Course
2、单链表的建立
单链表的建立是将先建立好的一个个结点串 联起来即可,也就是每个结点的指针域存储下 一个结点的地址。
21
CS&T Information Course
单链表的实现———单链表的建立
初始化
head
∧
算法描述:
/*为首节点分配内存空间*/
17
CS&T Information Course
单链表
空表和非空表不统一,缺点? 如何将空表与非空表统一? 空表 first=NULL 非空表
first a 1
a2
an ∧
18
CS&T Information Course
头结点:有时为了操作方便,在单链表的第一个结点之前添
加一个结点,称头结点或伪结点,头结点的数据域可以不存放 任何信息,也可以存放其他特殊信息,头结点的指针域存放第 一个元素结点的存储地址,即指向第一个结点的指针值。此时, 单链表的头指针指向头结点,称其为带头结点的单链表。
QIAN SUN
WANG WU ZHAO ZHENG ZHOU
13 1 NULL 37 7 19 25
SUN
1. 逻辑次序和物理次 序不一定相同。 2.元素之间的逻辑关 系用指针表示。
H
ZHAO
QIAN
LI
ZHOU
WU
ZHENG
WANG
^
5
CS&T Information Course
例 线性表 (3,5,8,9,12,6)
Pointer
New
New->Numer=2; strcpy(New->Name,”Bob”); New->next=NULL;
41
CS&T Information Course
Head
∧
1
Alan
2
Bob
^
Pointer
New
对应语句: Pointer->next=New;
42
CS&T Information Course
Head
∧
1
Alan
2
Bob ^
Pointer
New
对应语句: Pointer=New;
43
CS&T Information Course
Head
∧
1
Alan
2
Bob
^
3
Tom
^
Pointer
New
对应语句:
New=(student *)malloc(sizeof(student)); New->Numer=3; strcpy(New->Name,”Tom”); New->next=NULL;
35
∧
new
new->data=35; new->next=null; head->next=new; 依次插入每一个元素结点
23
CS&T Information Course
例如:
• 有一个链表存储了4个学生的简单信息,包括学号、姓 名。该链表数据域存储的学生信息,就不只一项了, 故结点的类型定义如下:
head=(Lnode *)malloc(sizeof(Lnode)); head->next=null;
22
CS&T Information Course
单链表的实现———单链表的建立
头插法:将待插入结点插在头结点的后面 。
插入第一个元素结点
head 算法描述:
∧ new=(Lnode *)malloc(sizeof(Lnode));
Pointer=Head;
38
CS&T Information Course
Head
∧
1
Alan
^
^
Pointer
^
New
对应语句:
New=(student *)malloc(sizeof(student)); New->Numer=1; strcpy(New->Name,”Alan”); New>next=NULL;
用法
若:Lnode *p; p=(Lnode *)malloc(sizeof(Lnode)); 此时,p和对象之间的关系:
14
CS&T Information Course
节点存储单元的动态释放:free函数 函数原型:void free(void *p);
函数功能:释放由p指向的内存区。
free(p);