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