数据结构与算法Python语言描述课件
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•}
• // 加工型——map操作! • void TraverseList(List &L,
Status GetElem(List L, int i, ElemType &e) {
// i 的合法性检测 if (i < 1 || i > L.length) return ERROR;
//取元素 e = L.elem[i-1];
• L.length = 0; • L.listsize = 0; •}
• // 引用型
• void TraverseList(List L, void (*visit)(ElemType)){
• for (i = 0; i < L.length; i++)
•
(*visit)(L.elem[i]);
•
它的前驱,否则操作失败,pre_e无定义。
•
NextElem( L, cur_e, &next_e )
//求数据元素的后继
•
初始条件:线性表L已存在。
• 操作结果:若cur_e是L的元素,但不是最后一个,则用next_e
•
返回它的后继,否则操作失败,next_e无定义。
– GetElem( L, i, &e ) //取线性表中第i个数据元素 • 初始条件:线性表L已存在,且1≤i≤LengthList(L)。 • 操作结果:用e返回L中第i个元素的值。
• q = &(L.elem[i-1]);
• for (p = &(L.elem[L.length-1]); p >= q; --p)
•
*(p+1) = *p;
删除操作: Status DeleteList( )
删除前的线性表:(a1,…,ai-1,ai,ai+1,…,an) 删除后的线性表:(a1,…,ai-1,ai+1,…,an)
} }
线性表类型的应用——归并操作
• 题目:已知线性表LA和LB中的数据元素按值非递 减有序排列,现要求将LA和LB归并为一个新的线 性表LC,且LC中的数据元素仍按值非递减有序排 列。
– 方法:设置两个指针分别指向LA和LB的当前元素,将 数值较小的元素插入LC中。
பைடு நூலகம்
void MergeList(List La, List Lb, List &Lc){
– LocateElem( L, e, compare() ) //定位函数
• 初始条件:线性表L已存在,e为给定值,
•
compare()是元素判定函数。
• 操作结果:返回第1个与e满足compare关系的元素 的位序。
• //加工型操作:&L !!!
• ClearList( &L ) //线性表置空
• typedef struct {
length
•
a1 a2 a3
ElemType *elem;
a4
//
存a储5 空a6 间a基7 址
listsize
• int elleemngth; // 当前长度
List类型的对象L
listsize 10 length 3
elem
279
2020/7/1
动态内存空间
return OK; }
int LocateElem(List L, ElemType e, Status (*compare)(ElemType, ElemType)) {
//起步 i = 1; p = L.elem;
//在有效范围内查询 while(i <= L.length && !(*compare)(*p++, e)) ++i;
•
初始条件:线性表L已存在。
•
操作结果:将L重置为空表
• ListInsert( &L, i, e ) //插入数据元素
•
初始条件:线性表L已存在,且
1≤i≤LengthList(L)+1 。
线性表类型的应用——求集合的并集
• 题目:假设利用两个线性表LA和LB分别表示两 个集合A和B,现要求一个新的集合A=A∪B。
• Status InsertList(List &L, int i, ElemType e) {
• //插入范围的合法性检测 • if (i < 1 || i > L.length+1) return ERROR;
• //空间不够,追加
• if(L.length >= L.listsize) {
}
while (i <= La_len) { GetElem(La, i++, ai); ListInsert(Lc, ++k, ai);
} while (j <= Lb_len) {
GetElem(Lb, j++, bj); ListInsert(Lc, ++k, bj); } }
线性表的表示和实现
2016 Fall《数据结构》
第三章 线性表
内容提要
• 线性结构 • 线性表的类型定义 • 线性表的顺序表示和实现 • 线性表的链式表示和实现
线性结构
何处用到线性结构???
• 学生信息表 • 通讯录 • 短信、聊天记录 • 邮件列表 • 购物清单 • 账单
线性表
首元素
相邻的元素 组成前驱与后继关系
线性表类型
• ADT List { – 数据对象:D={ ai | ai ∈ ElemSet, i = 1,2,...,n, n≥0 }
– 数据关系:R1={ <ai-1, ai> | ai-1, ai∈D, i = 2,...,n }
– 基本操作:
•
InitList( &L ) //初始化
•
操作结果:构造一个空的线性表L。
ClearList(Lc);
// 这里假定Lc已经做过InitList操作, // ClearList之后表的空间还在!
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) {ListInsert(Lc, ++k, ai); ++i;} else {ListInsert(Lc, ++k, bj); ++j;}
•
ListEmpty( L ) //判断线性表是否为空
•
初始条件:线性表L已存在。
•
操作结果:若L不空,返回true,否则为false。
•
PriorElem( L, cur_e, &pre_e )
//求数据元素的前驱
•
初始条件:线性表L已存在。
• 操作结果:若cur_e是L的元素,但不是第一个,则用pre_e返回
•
CreatList( &L, n ) //创建
•
操作结果:构造一个含n个元素的线性表L。
•
DestroyList( &L ) //结构销毁
•
初始条件:线性表L已存在。
•
操作结果:销毁线性表L。
• //引用型操作
•
ListLength( L ) //求线性表的长度
•
初始条件:线性表L已存在。
•
操作结果:返回L中元素个数。
线性表的逻辑结构
尾元素
线性表
• 线性表是n个数据元素的有限序列。 • 一般形式:(a1,…,ai-1,ai,ai+1,…,an)
• 直接前驱、直接后继 • 长度:表中元素的个数n (n=0时称为空表) • 非空表中,每个元素都有一个确定的位置
线性表抽象数据类型?
• 结构 + 操作
– 结构的创建、结构的销毁:构造与析构 – 引用型(访问型):get – 加工型(改变型):set
•
newbase = (ElemType *)realloc(L.elem,
• (L.listsize+LISTINCREMENT)*sizeof(ElemType));
•
• if (!newbase) exit(OVERFLOW);
• 【数组方式的元素移动、插入】
• //从插入位置开始向后的元素,自后向前依次后 移
数学科学学院
21
顺序存储时基本操作的实现
• Status InitList(List &L) {
• //分配空间
• L.elem = (ElemType *)malloc(LIST_INIT_SIZE
•
*sizeof(ElemType));
• if(!L.elem) exit(OVERFLOW);
//自前向后前移元素 q = L.elem + L.length - 1; for(++p; p <= q; ++p) *(p-1) = *p;
//修改表长 --L.length;
return OK; }
// 两个表的有序归并 // 此处作为List类型的基本操作直接定义!!!
void MergeList(List La, List Lb, List &Lc){
• 线性表的顺序表示和实现
• 线性表的链式表示和实现
线性表的顺序表示
• 是指用一组地址连续的存储单元依次存放线性表 的数据元素
以元素在计算机内“物理位置相邻”来表示线性表中数 据元素之间的逻辑相邻
线性表的顺序表示和实现
• 是指用一组地址连续的存储单元依次存放线性表 的数据元素
设每个数据元素需占用C个存储单元 – LOC(ai) = LOC(ai-1) + C – LOC(ai) = LOC(a1) + (i-1)×C
• //空间总长赋初值
• L.listsize = LIST_INIT_SIZE;
•
length=0
• //表长赋初值0 • L.length = 0;
elem
listsize
• 【结构的销毁——没有空间了!】 • void DestroyList(List &L) { • //空间释放 • free(L.elem); • L.elem = NULL;
线性表的顺序表示和实现
• 是指用一组地址连续的存储单元依次存放线性表 的数据元素
线性表的顺序存储结构是一种能够随机存取的存储结 构,通常用动态数组来实现。
顺序存储结构的表示
• #define LIST_INIT_SIZE 100 // 线性表存储空间的初 始分配量
• #define LISTINCREMENT 10 // 线性表存储空间的分 配增量
时间复杂度:最坏和平均的情况O(n) 逻辑关系发生了变化
Status DeleteList(List &L, int i, ElemType &e) {
//合法性检测 if ((i < 1) || (i > L.length)) return ERROR;
//取出元素带回 p = &(L.elem[i-1]); e = *p;
【此处应细致考虑,如果Lc.elem != NULL,要先做销毁 DestroyList操作,再重新开空间!】
//返回元素的真实位置 if (i <= L.length) return i; else return 0;
}
int LocateElem(List L, ElemType e, Status (*compare)(ElemType, ElemType)) {
//起步 i = 1;
//在有效范围内查询 while(i<=L.length && !(*compare)(L.elem[i-1], e)) ++i;
– 方法:只要从LB中依次取出每个数据元素,并依值在 LA中进行查访,若不存在,则插入。
线性表类型的应用——求集合的并集
void unionSet(List &La, List Lb){
La_len = ListLength(La); Lb_len = ListLength(Lb);
for(i = 1; i <= Lb_len; i++){ GetElem(Lb, i, e); if(!LocateElem(La, e, EQUAL)) InsertList(La, ++La_len, e);
//返回元素的真实位置 if (i <= L.length) return i; else return 0;
}
插入操作:Status InsertList( )
插入前的线性表:(a1,…,ai-1,ai,ai+1,…,an) 插入后的线性表:(a1,…,ai-1,b,ai,ai+1,…,an)
时间复杂度:最坏和平均的情况O(n) 逻辑关系发生了变化
• for(j = L.length; j>=i; j--) {
•
L.elem[j] = L.elem[j-1];
•} • • //插入e,修改表长
• L.elem[i-1] = e;
• ++L.length;
• return OK;
• 【指针方式的元素移动、插入,有些难以阅 读。。。。】
• //从插入位置开始向后的元素,自后向前依次后 移