济南大学数据结构 第二章

合集下载

《数据结构》课件第二章

《数据结构》课件第二章

线性表的基本操作(逻辑)
➢ 构造一个空表L ➢ 获取L的长度(即元素个数) ➢ 访问L中第i个数据元素的值 ➢ 访问L中第i个数据元素的前驱/后继的值 ➢ 在L中第i个元素之前插入新的元素e ➢ 删除L的第i个数据元素
➢ 注意在插入或者删除之后,线性表的长度应 能随之改变
一 顺序存储
➢ 线性表的顺序表示:用一组地址连续的存储单 元依次存储线性表的数据元素。

将Temp_b插入到 LC的第k个位置上
Temp_a ≤ Temp_b
是 将Temp_a插入到 LC的第k个位置上
否 i ≤ LA.len 否
j← j + 1
i← i + 1
j ≤ LB.len
Temp_a = Temp_b



j← j + 1
k← k + 1
结束

将LA表的第i个元 素插入到LC表的
插入操作的时间复杂度 O(n/2) 链表中的插入、删除操作没有上溢的情况, 并且节省内存资源
思考:若现已知道指向某元素节点的指针 p,希望能在该节点之前插入元素x,该如 何操作?其算法时间复杂度是多少?
3) 单链表的删除
p
删除第i个元素,由e返回值 删除b
a
Hale Waihona Puke bc … 1) 寻找第i-1个结点
2) 保留结点b的地址
9 SHI 5
0
1
1 ZHAO 2
2 QIAN 3
3 SUN 4
4 LI
9
5 ZHOU 6
6 WU 8
7 ZHENG 8
8 WANG 0
9 SHI 5
i=s[i].cur 指针后移

数据结构第二章答案课件

数据结构第二章答案课件

a1 a2

an e …
}
S.base
S.topS.top
Status Pop (SqStack &S, ElemType &e) {
// 若栈不空,则删除S的栈顶元素,
// 用e返回其值,并返回OK;
// 否则返回ERROR
if (S.top == S.base) return ERROR;
e = *--S.top;
1 (n 0,1)
相应的算法:
n! n * (n 1)! (n 1)
float fact(int n)
{ if (n==0||n==1) s=1;
else s=n*fact(n-1);
return s; }
若求5!,递归调用执行过程:
主函数 mani() printf(“fact(5)”)
输出 s=120.00
尽管一生只在学校里读过三个月的书但通过勤奋好学勤于思考发明了电灯电报留声机电影等一千多种成果成为著名的发明家例一数制转换例二括号匹配的检验例三表达式求值313尽管一生只在学校里读过三个月的书但通过勤奋好学勤于思考发明了电灯电报留声机电影等一千多种成果成为著名的发明家例一数制转换十进制数n和其他d进制数的转换算法基于以下原理
第一层调用
n=5 s=5*fact(4)
fact(5) =120
第二层调用
n=4 s=4*fact(3)
fact(4) =24
每一次递归调用并未立即得到
结果,而是进一步向深度递归
调用,直到n=1或n=0时,函数 fact才有结果为1,然后再一一 返回计算,最终得到结果。
第三层调用
n=3 s=3*fact(2)
例二、 括号匹配的检验

《数据结构(C语言版)》电子教案第2章

《数据结构(C语言版)》电子教案第2章

数据元素,返回一特殊值(例如0),表示查找失败。
(5) 插入元素Inselem (L,i,x) 在线性表L的第 i 个位置上插入一个值为 x 的新元素,这样 使原序号为 i , i+1, ..., n 的数据元素的序号变为 i+1,i+2, ..., n+1,要求1≤i≤Getlen(L)+1,插入后原表长增1。 (6) 删除元素Delelem(L,i) 在线性表L中删除序号为i的数据元素,删除后使序号为 i+1, i+2,..., n 的元素变为序号i, i+1,...,n-1,要求1≤i≤Getlen(L), 删除后表长减1。
typedef int ElemType //在实际应用中,将ElemType定义成实际类型 typedef struct{ ElemType data[MaxLen]; //定义存储表中元素的数组 int length; //线性表的实际长度 }sqList; sqList L; //定义表结构的变量
E in
2012-9-12

i 1
n 1
p i ( n i 1)
1 n 1

i 1
n 1
( n i 1)
n 2
18
由此可以看出,在线性表上做插入操作需要移动表中一 半的数据元素,当n较大时,算法的效率是比较低的,所以 在线性表上进行插入操作的时间复杂度为O(n)。 6.顺序表的删除运算Delelem(L,i)的实现 顺序表的删除运算是指将表中第 i 个元素从线性表中去
i+1。
线性表是一种典型的线性结构。 数据的运算是定义在逻辑结构上的,而运算的具体实现则 是在存储结构上进行的。
2012-9-12

数据结构教案第二章

数据结构教案第二章

1、建空表:Initlist (&L);
2、求表长度:Listlength(L):返回L中数据元素个数
3、按序号取值:GetElem(L,i,&e):用 e 返回L中第i数据元素的值
4、按值查找:LocateElem(L,e,compare()) 初始条件:线性表 L 已存在,compare()是数据元素判定函数
课程名称 教材 授课内容
数据结构
教学对象
数据结构(C 语言)
第二章 线性表
新华软工专业
课时
2
教学目的
本章主要介绍线性表的定义、运算和线性表的几种存储结
与要求 构等内容
重点、难点
重点:线性表的定义、线性表的基本操作,线性表的存储结构 难点:线性表的基本操作,线性表的存储结构
课型
电脑+理论
教学方法
投影、讨论、板书
以它的操作与其它位置不同,这将造成同一数据结构上操作的不一致性,不 科学
因此,在表头前一个结点--头结点,使单链表成为带头结点的单链表, 既可解决操作一致性的问题
以后,我们将在该结构上讨论操作 说明:
在单链表中,每一个元素的存储位置都包含在其直接前驱结点的信息之 中
有:P指向 ai 元素 p->next 指向 ai+1 元素
3、线性链表基本操作的算法:(用时 40 分钟)
如何在线性链表的实现基本操作?如何建表?如何插入?删除? 约定带头结点的线性链表存储线性表
1)初始化操作: 功能:建空线性表 参数:head 为线性链表的头指针 主要步聚:调用 malloc()分配一结点的空间,并将其地址赋值给 head
算法: LNode *create-head( ) { LNode *head; head=(Linklist )malloc(sizeof(LNode)); head->next=NULL; Return (head);

数据结构第2章b-12级

数据结构第2章b-12级

第2章 线 性 表
2.3.2 单链表上的基本运算
• 建立
– 头插法: – 尾插法: – 带头结点的尾插法:
• 查找 • 删除运算
第2章 线 性 表
一、建立单链表
尾插法建表 头插法建表 从空表开始 重复读入数据 创建新结点 将新结点插入到链 表的表头上 直到读入结束标志 从空表开始 重复读入数据 创建新结点 将新结点插入到当 前链表的表尾上 直到读入结束标志
第2章 线 性 表
前插操作图示:
原链表序列: a1,a2,……ai-1,ai 插入后链表序列:a1,a2,……ai-1,x,ai
q
head
p ai x
a1 s
ai-1
第2章 线 性 表
前插操作具体算法如下:
void INSERTBEFORE(linklist *head, linklist *p, datatype x) { linklist *s,*q; s=(linklist *)malloc(sizeof(linklist)); s->data=x; q=head; while(q->next!=p)q=q->next; s->next=p; q->next=s; }
第2章 线 性 表
思 考
• (1)观察头指针head的变化 • (2)单链表中每一个新结点的 产生过程是否完全相同 • (3)生成链表中结点的顺序与 输入顺序有什么关系
第2章 线 性 表
第2章 线 性 表
• (1) 头插法建表 从一个空表开始,重复读入数据,生成新结点,将 读入数据存放在新结点的数据域中,然后将新结点插 入到当前链表的表头上,直到读入结束标志为止。
第2章 线 性 表

数据结构课件-第二章

数据结构课件-第二章

1初始化单链表 Void InitList(LinkList *head) {/* 初始化单链表 */ head=(LinkList)malloc(Sizeof(ListNode)) /*申请头结点空间,并使头指针head指向头结点 */ head->next=NULL; /* 置链尾标记NULL */ }
2.4线性表的链式存储结构

链式存储结构用一组任意的存储单元依次存储 线性表里元素,这组存储单元可以是连续的, 也可以是不连续的,甚至是零散分布在内存的 任何位置上。

为反映出各元素在线性表中的逻辑关系,对每 个数据元素来说,除了存储其本身的信息之外 ,还需存储一个指示其直接后继的信息(即直 接后继的存储位置)。这两部分信息组成一个 数据元素的存储映象,称为结点(Node)。

例如,图2-4-2所示为线性表(dog,pig,cat,fox,hen,bat ,bee,bird)的单链表存储结构,整个链表的存取需从头指针开始 进行,依次顺着每个结点的指针域next找到线性表的各个元素,直 至next域为空为止。

通常我们用箭头表示链域中的指针:
typedef struct Node {ElemType data; /*数据域*/ struct Node *next; /*指针域*/ }ListNode,*LinkList;
2.3.1 线性表的顺序存储

线性表的顺序存储是指用一组地址连续的存储单元依 次存储线性表中的各个元素,使得线性表中在逻辑结 构上相邻的数据元素存储在相邻的存储单元中 。

假设线性表中有n个数据元素,每个数据元素占K个 存储单元,第一个元素a1的存储地址用LOC(a1)表示 ,第i个数据元素ai的地址用LOC(ai)表示,则: 第i个数据元素的地址为: LOC(ai)=LOC(a1)+(i-1)×K (1≤i≤n)

《数据结构(C++版)(第二版)》第02章

《数据结构(C++版)(第二版)》第02章
13
2.2.3 顺序表存储空间的动态分配
上面介绍的线性表顺序存储,是预先给定大小为maxsize的存储空间,程序在编译 阶段就会知道该类型变量的大小,在程序开始运行前,就会为它分配好存储空间, 故是一种存储空间的静态分配。而动态分配是在定义线性表的存储类型时,不是定 义好一个数组空间,而是只定义一个指针,待程序运行后再申请一个用于存储线性 表的空间,并把该空间的首地址赋给这个指针。访问动态存储分配的线性表中的元 素和访问静态存储分配的线性表中的元素的情况完全相同,既可以采用指针方式, 也可以采用数组下标方式。 若将前面线性表的顺序存储结构类型中的数组形式改为指针形式,则得到动态分配 形式如下: class sequenlist { public: elemtype *a; int len; …… };
2
2.线性表的特征 从线性表的定义可以看出线性表的特征: (1)有且仅有一个开始结点(表头结点)a1,它没有直接前驱,只有一个直接 后继; (2)有且仅有一个终端结点(表尾结点)an,它没有直接后继,只有一个直接 前驱; (3)其他结点都有一个直接前驱和直接后继; ( 4)元素之间为一对一的线性关系。 因此,线性表是一种典型的线性结构,用二元组表示为: linear_list=(A,R) 其中 A={ai ∣1≤i≤n,n≥0,ai∈elemtype} R={r} r={<ai,ai+1> ∣1≤i≤n-1} 对应的逻辑结构图如下所示。
4
2.1.3 线性表的抽象数据类型描述
上述这些操作可用抽象数据类型描述为: ADT Linearlist is Data: 一个线性表L定义为L=(a1,a2,…,an),当L=()时定义为一个空表。 Operation: void setnull(&L) //将线性表L置成空表 int Length(L) //求给定线性表L的长度 elemtype Get(L,i) //取线性表L第i个位置上的元素 elemtype Prior(L,x) //求线性表L中元素值为x的直接前驱 elemtype Next(L,x) //求线性表L中元素值为x的直接后继 int Locate(L,x) //在线性表L中查找值为x的元素位置 void Insert(&L,x,i) //在线性表L中第i个位置上插入值为x的元素 void Dele(&L,i) //删除线性表L中第i个位置上的元素 END Linearlist

数据结构(第二章)

数据结构(第二章)

建立顺序表
void creat_sqlist(Sqlist L) { int i,n; cout<<"n=?; cin>>n; L.length=n; for (i=0; i<n; i++) cin>>L.a[i]; }
initlist(Sl);
输出顺序表
void outputl(Sqlist L) { int i; cout<<"List length" <<L.length<<endl; for (i=0; i<L.length; i++) { cout<<L.a[i]<<" "; if ((i+1)%10==0) cout<<endl; } cout<<endl; }
4. 合并:两表分别非递减有序(递增或等值),合并后 仍然非递减有序。
void merge_list(Sqlist a, Sqlist b, Sqlist &c) { int i,j,k; i=j=k=0; c.length=a.length+b.length; while (i<=a.length-1 && j<=b.length-1) { if (a.a[i]<=b.a[j]) {c.a[k]=a.a[i]; i++; k++;} else {c.a[k]=b.a[j]; j++; k++;} } while (i<=a.length-1) { c.a[k]=a.a[i]; i++; k++; } while (j<=b.length-1) { c.a[k]=b.a[j]; j++; k++; } }

数据结构(第二版)课后习题答案

数据结构(第二版)课后习题答案

数据结构(第二版)课后习题答案第一章:数据结构概述数据结构是计算机科学中非常重要的一个概念,它用于组织和管理计算机内部存储的数据。

数据结构的设计直接影响到程序的运行效率和对真实世界问题的建模能力。

第二版的《数据结构》教材旨在帮助读者更好地理解和应用数据结构。

为了提高学习效果,每章节后都附有一系列习题。

本文将为第二版《数据结构》教材中的部分习题提供详细的答案和解析。

第二章:线性表2.1 顺序表习题1:请问如何判断顺序表是否为空表?答案:当顺序表的长度为0时,即为空表。

解析:顺序表是用一块连续的内存空间存储数据元素的线性结构。

当顺序表中没有元素时,长度为0,即为空表。

习题2:如何求顺序表中第i个元素的值?答案:可以通过访问顺序表的第i-1个位置来获取第i个元素的值。

解析:顺序表中的元素在内存中是连续存储的,通过下标访问元素时,需要将下标减1,因为数组是从0开始编号的。

2.2 链表习题1:请问链表中的结点包含哪些信息?答案:链表的结点一般包含两部分信息:数据域和指针域。

解析:数据域用于存储数据元素的值,指针域用于存储指向下一个结点的指针。

习题2:如何删除链表中的一个结点?答案:删除链表中的一个结点需要将其前一个结点的指针指向其后一个结点,然后释放被删除结点的内存空间。

解析:链表的删除操作相对简单,只需要通过修改指针的指向即可。

但需要注意释放被删除结点的内存空间,防止内存泄漏。

第三章:栈和队列3.1 栈习题1:如何判断栈是否为空?答案:当栈中没有任何元素时,即为空栈。

解析:栈是一种先进后出(Last In First Out,LIFO)的数据结构,栈顶指针指向栈顶元素。

当栈中没有元素时,栈顶指针为空。

习题2:请问入栈和出栈操作的时间复杂度是多少?答案:入栈和出栈操作的时间复杂度均为O(1)。

解析:栈的入栈和出栈操作只涉及栈顶指针的改变,不受栈中元素数量的影响,因此时间复杂度为O(1)。

3.2 队列习题1:请问队列可以用哪些方式实现?答案:队列可以用数组或链表来实现。

数据结构课件CHAPTER2

数据结构课件CHAPTER2

a1
a2
a3
a4
a5
a6
直接前驱和直接后继描述了结点之间的逻辑关系 (即邻接关系)
Department of Computer Science & Technology, Nanjing university fall
线性表的抽象基类 template <class T, class E> class LinearList { public: LinearList(); //构造函数 //析构函数 〜~LinearList(); virtual int Size() const = 0; //求表最大大体积 virtual int Length() const = 0; //求表⻓长度 virtual int Search(T x) const = 0; //搜索 virtual int Locate(int i) const = 0; //定位 virtual E* getData(int i) const = 0; //取值 virtual void setData(int i, E x) = 0; //赋值
Nanjing university
fall
删除的主要思想: (1) 在顺序表中查找x,如果x在表中不存在,则 不能删除;
Data Structures
(2)如果x在表中存在,设x在顺序表中的位置 为i; (3) 将顺序表的最后位置减1; (4)把顺序表中原来第i+1至第n-1个表项依次向 前移动一个表项位置
Department of Computer Science & Technology, Nanjing university fall
Data Structures

数据结构第二章课后答案.

数据结构第二章课后答案.

数据结构第二章课后答案.在数据结构的学习中,第二章通常会涉及一些关键的概念和知识点。

让我们一起来详细探讨一下。

首先,我们要明确数据结构中一些基本的定义和分类。

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

在第二章中,常见的比如线性表就是一个重要的结构。

线性表是一种最简单也是最常用的数据结构之一。

它具有有限个相同数据类型的元素组成的有序序列。

从存储结构上来看,线性表可以分为顺序存储和链式存储。

顺序存储的线性表,就像是在一个连续的存储空间中,依次存放着线性表的元素。

优点是可以随机访问,即通过下标就能快速找到对应的元素。

但缺点也很明显,插入和删除操作可能需要移动大量的元素,比较费时。

而链式存储的线性表,则是通过指针将各个元素链接起来。

每个节点包含数据域和指针域。

这种存储方式的优点是插入和删除操作比较方便,只需要修改指针即可。

但缺点是不能随机访问,需要从头节点开始依次遍历才能找到目标元素。

在实际应用中,选择哪种存储方式要根据具体的需求来决定。

如果经常需要进行随机访问,而插入和删除操作较少,那么顺序存储可能更合适;如果插入和删除操作频繁,而对随机访问的要求不高,链式存储则更具优势。

再来说说线性表的基本操作。

比如初始化线性表,就是为线性表分配存储空间,并将其初始化为空。

还有求线性表的长度,通过遍历节点来计算元素的个数。

插入操作分为在指定位置插入和在表尾插入。

在指定位置插入时,需要先将插入位置后面的元素依次向后移动,然后再将新元素插入。

删除操作也类似,需要先找到要删除的元素,然后将其后面的元素依次向前移动。

对于线性表的遍历,常见的有顺序遍历和逆序遍历。

顺序遍历就是从表头开始,依次访问每个元素;逆序遍历则是从表尾开始向前访问。

接下来,我们看一些具体的例子。

比如一个学生成绩管理系统,我们可以用线性表来存储学生的成绩信息。

如果需要经常添加或删除学生成绩,那么采用链式存储会更方便操作。

再比如一个图书馆的图书管理系统,用线性表来存储图书的信息。

《数据结构A》第02章

《数据结构A》第02章

……. private:
Node<T>* first; };
顺序表类SeqList、单链表类SingleList是抽象线性 表类LinearList类的派生类。
LinearList
SeqList
SingleList
friend Node
构造函数 SingleList(){ first=NULL; n=0; }
} 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; }
void main() {
线性表ADT
ADT LinearList { 数据:
0个或多个元素的线性序列(a0,a1,...,an-1),其最 大允许长度为MaxListSize。 运算:
Create(): 创建一个空线性表。 Destroy():撤消一个线性表。 IsEmpty():若线性表空,则返回true;否则返 回false。 Length(): 返回表中元素个数。
……
LinearList
SingleList
…… private://私有数据
int maxLength; //顺序表的最大长度 T *elements; //动态一维数组的指针
};
动态存储分配 构造函数,构建一个空线性表
template <class T> SeqList<T>::SeqList(int mSize) {

数据结构课件ppt第二章

数据结构课件ppt第二章
答:由于顺序存储结构一旦确定了起始位置, 线性表中的任何一个元素都可以进行随机存 取,即存取速度较高;并且,由于线性表的 总数基本稳定,且很少进行插入和删除,故 这一特点恰好避开了顺序存储结构的缺点。 因此,应选用顺序存储结构。
3. 在单链表和双向链表中,能否从当前结点 出发访问到任一结点?
• 答:在单链表中只能由当前结点访问其后 继的任一结点,但因其没有指向前驱的指 针而无法访问其前驱结点。在双向链表中, 由于当前结点既有指向后继的指针,又有 指向前驱的指针,所以在双向链表中可以 由当前结点出发访问表中的任何一个结点。
data 0
1
a2
2
a1
3
4
a3
cursor 2 4 1
0
data 0
1
a2
2
a1
3
a4
4
a3
cursor 2 3 1
4 0




maxsize-1
maxsize-1
静态链表的C语言描述
//线性表的静态链表存储结构 # define MAXSIZE 100 //链表的最大长度 typedef struct {
D. 循环链表
答案:C,D
A,C,D
写出带头结点的双向循环链表L为空表的 条件:
空表 L
答案:(L==L->next)&&(L==L->prior)
判断题
1. 在具有头结点的链式存储结构中,头指针 指向链表中的数据结点。( )
2. 顺序存储的线性表可以随机存取。( ) 3. 在单链表中,要访问某个结点,只要知道
} DuLNode, *DuLinkList;
2. 循环链表
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第二章线性表线性结构特点:•唯一头元素•唯一尾元素•除头元素外,均有一个直接前驱•除尾元素外,均有一个直接后继书目信息、排队、算术表达式。

2.1 线性表的定义1. 线性表的语言定义线性表是n个数据元素的有限序列。

例,英文字母表(A,B,C,……,Z)线性表中的数据元素也可以由若干个数据项构成。

例,包含大量记录的登记表线性表可以表示为n 个数据元素的有限序列: (a1,…,a i-1,a i,…,a n)其中a1是头元素,a n是尾元素,a i是第i 个元素。

a i-1是a i的直接前驱,a i是a i-1的直接后继。

抽象数据类型线性表List 的定义:ADT List {数据对象: D = { a i | a i∈ElemSet,i = 1, 2, …, n }数据关系: R1 = { < a i-1, a i > }基本操作:InitList( &L )结果: 构造一个空的线性表L。

DestroyList( &L )条件: 线性表L 已存在。

…} ADT List其它基本操作包括:ClearList( &L )ListEmpty ( L )ListLength ( L )GetElem ( L,i,&e )LocateElem ( L,e,compare() )PriorElem ( L,cur_e,&pre_e )NextElem ( L,cur_e,&next_e )ListInsert ( &L,i,e )ListDelete ( &L,i,&e )ListTraverse ( L,visit() )2.2 线性表的顺序表示和实现线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。

线性表顺序存储结构表示# define LIST_INIT_SIZE 100# define LISTINCREMENT 10typedef struct {Elemtype* elem; //数据元素int length; // 表长,初始为0int listsize; // 表存储容量} SqList;Status InitList_Sq ( SqList &L ) { //初始化空线性表L.elem = ( ElemType * ) malloc( LIST_INIT_SIZE * sizeof(ElemType) );if ( ! L.elem ) exit(OVERFLOW) ;L.length = 0 ;L.listsize = LIST_INIT_SIZE ;return OK ;}线性表的顺序存储结构的优点•可随机存取表中任意数据元素(第i 个)L.elem[i-1]* (L.elem+i-1)•直接可获取线性表的长度L.length算法2.4 在第i个数据元素之前插入一个新的元素例,在第i 个元素前插入b思想:1. 找到第i个元素的位置。

2. 将第n到i个元素均向后移动一个位置。

3. 将新元素放置在第i个位置。

int ListInsert_Sq ( Sqlist &L ,int i ,ElemType e ) {ElemType *p, *q;q = & L.elem[i-1] ;//找到第i 个元素位置for ( p = & L.elem[L.length-1] ;p >= q ;p -- )* (p+1) = * p ;// 后移元素* q = e ;// 插入新元素++L.length ;return 0;}int ListDelete_Sq ( Sqlist &L ,int i ,ElemType &e ) {if ( i < 1 || i > L.length ) return 1 ;p = & L.elem[i-1] ;// 找到第i 个元素e= * p ;// 取第i 个元素的值for ( p++ ;p <= & L.elem[ L.length - 1];p ++ )* (p - 1) = * p ;// 前移-- L.length;return 0 ;}2.3 线性表的链式表示和实现线性表的链式存储结构的特点是用一组随意的存储单元存储线性表的数据元素。

例,线性表数据为{3,5,7}结点: 两部分信息组成,存储数据元素信息的数据域,存储直接后继存储位置信息的指针域。

线性表的单链表存储结构typedef struct LNode {ElemType data ;struct LNode * next ;} * LinkList ;2.3.1 线性单链表Head: 头指针,指向链表中第一个结点。

0: 空指针,有时也表示为“NULL”或“∧”。

头结点: 为了某些操作的方便,通常在链表第一个结点之前附加一个结点,没有实际意义。

空表:线性表的链式存储结构的特点缺点:•不可随机存取表中任意数据元素•不可直接获取线性表的长度算法2.8: 取出线性单链表第i个元素。

思想:1. 找到第1 个元素;2. 循环找到第i个元素;3. 取出元素;Status GetElem_L ( LinkList L,int i,ElemType &e ) { p = L->next ;j = 1 ;//p指向第一个元素,j计数while ( p && j < i ) {p = p->next ;++j ;//循环找到第i 个元素}if ( ! p || j > i ) return ERROR ;e = p->data ;return OK ;}例,取出第i=3个元素。

e = p->data = Sun平均时间复杂度: O(n)优点:数据元素的插入、删除相对方便在b之前插入元素x :1. 找到b结点的前驱结点2. 构造将要插入的结点3. 指针变换算法2.9 在第i个数据元素之前插入一个新的元素Status ListInsert_L ( LinkList &L ,int i ,ElemType e ) {1. 找到第i 个结点的前驱结点2. 构造将要插入的结点3. 指针变换}Status ListInsert_L ( LinkList &L ,int i ,ElemType e ) { p = L;j = 0;while ( p && j < i - 1 ) { p = p->next ;++j ;}//找到第i 个结点的前驱结点if ( ! p || j > i - 1 ) return ERROR ;s = ( LinkList ) malloc ( sizeof (LNode) ) ;s->data = e ;s->next = NULL ;//建立新结点s->next = p->next ;p->next = s ;//插入新结点return OK ;}例,在第3个元素之插入一个新元素。

p->next = ss->next = p->next平均时间复杂度: O(n)算法2.11 利用插入操作构造一条完整的单链表。

void CreateList_L ( LinkList &L,int n ) {L = ( LinkList ) malloc ( sizeof (LNode) ) ;L->next = NULL ;//建立头结点for ( i = n ;i > 0 ;--i ) {p = ( LinkList ) malloc ( sizeof (LNode) ) ;Scanf ( &p->data ) ;p->next = L->next ;L->next = p ;//在表头插入新结点}}例,讨论: 如何逆置一个单链表为一个新表?作业: 设计算法,将单链表L 中的第i 个结点和其后继结点交换位置,要求只修改指针。

删除元素b :1. 确定指针2. 取出要删除的结点3. 指针变换4. 释放内存1)p ->next = p ->next ->next2)q = p->nextp->next = q->nextfree(q) ;讨论单链表的删除操作,课堂演讲。

2.3.2 其他线性链表•循环链表•双向链表从某个结点出发寻找直接后继?从某个结点出发寻找直接前驱?1. 循环链表表中最后一个结点的指针域指向头结点,形成一个环。

优点:从表的任意结点出发均可以找到表中的任意其他结点。

空表:操作与线性单链表基本一致,差别只是在于算法中的循环结束条件不是p是否为空,而是p是否等于头指针。

例,取循环链表第i 个元素。

Status GetElem_L ( LinkList L,int i,ElemType &e ) { p = L->next ;j = 1 ;while ( p <> L && j < i ) {p = p->next ;++j ;}if ( p == L || j > i ) return ERROR ;e = p->data ;return OK ;}顺次合并两个线性表有时为了方便某些操作,通常在循环链表中设立尾指针。

Tail2->next = Tail1->nextp = Tail2->next ->nextTail2->next = Tail1->nextTail1->next = pp = Tail2->next ->nextq = Tail2->nextTail2->next = Tail1->nextTail1->next = pFree(q)在循环链表中寻找结点的直接后继很简单,只需要O(1);但要寻找结点的直接前趋需要循环一遍,需要O(n)。

2. 双向循环链表双向循环链表的结点有两个指针域: 一个指向直接后继,一个指向直接前趋。

typedef struct DuLNode{ElemType data ;struct DuLNode * prior ;struct DuLNode * next ;}DuLNode ,* DuLinkList ;空表:性质: 设d 是指向某个结点的指针,则有d->next->prior = d->prior->next = d操作: 插入、删除操作将会处理两个方向。

相关文档
最新文档