严蔚敏视频 笔记04
用一组地址连续的存储单元依次存放线性表中的数据元素
顺序映象的C语言描述
#define LIST_INIT_SIZE 80 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef struct {
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
} 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;
}
定位操作
int LocateElem_Sq(SqList L,ElemType e,Status (*compare)(ElemType, ElemType)) {
// 在顺序表L中查找第1个值与 e 满足判定条件
compare()的元素,
// 若找到,则返回其在L中的位序,否则返回0
i=1; // i 的初值为第1元素的位序
p=L.elem; // p 的初值为第1元素的存储位置
while(i<=L.length&&!(*compare)(*p++,e))
++i; // 依次进行判定
if(i<=L.length) return i; // 找到满足判定条件的数据元素为第i个元素
else return 0; // 该线性表中不存在满足判定的数据元素
}
时间复杂度为:O(ListLength(L))
插入操作
Status ListInsert_Sq(SqList &L,int pos,ElemType e)
{
if(pos<1||pos>L.length+1) return ERROR; // 插入位置不合法
if(L.length>=L.listsize) { // 当前存储空间已满,增加分配
newbase=(ElemType*)realloc(L.elem,(L.lsitsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW); // 存储分配失败
L.elem=newbase; // 新基址
l.listsize+=LISTINCREMENT; // 增加存储容量
}
q=&(L.elem[pos-1]); // q指示插入位置
for(p=&(L.elem[L.length-1]);p>=q;--p)
*(p+1)=*p; // 插入位置及之后的元素右移
*q=e; // 插入 e
++L.length; // 表长增1
return OK;
}
时间复杂度为:O(ListLength(L))
考虑平均情况 移动元素次数为n/2
删除操作
Status ListDelete_Sq(SqList &L,int pos,ElemType &e)
{
if ((pos<1)||(pos> L.length)) return ERROR; // 删除位置不合法
p=&(L.elem[pos-1]); // p为被删除的元素的位置
e=*p; // 被删除元素的值赋给e
q=L.elem+L.length-1; // 表尾元素的位置
for (++p;p<=q;++p) *(p-1)=*p; // 被删除元素之后的元素左移
--L.length; // 表长减1
return OK;
}
时间复杂度为:O(ListLength(L))
考虑平均情况 移动元素次数为(n-1)/2
2.3 线性表类型的实现——链式映象
单链表
用一组地址任意的存储单元存放线性表中的数据元素
以元素(数据元素的映象)+指针(指示后继元素存储位置的)=结点(表述数据元素)
以“结点的序列”表示线性表——称作链表
用第一个数据元素的存储地址作为线性表的地址,头指针
头结点
数据域 指针域
空表 头结点指针域为空
结点和单链表的C语言描述
typedef struct LNode {
ElemType data; // 数据域
struct LNode *next; // 指针域
} LNode,*LinkList;
操作的实现
取元素操作
Status GetElem_L(LinkList L,int pos,ElemType &e) {
p=L->next; j=1; // 初始化,p指向第一个结点,j为计数器
while(p&&j<pos) {p=p->next; ++j;}
// 顺指针向后查找,直到p指向第pos个元素或p为空
if(!p||j>pos) return ERROR; // 第pos个元素不存在
e=p->data; // 取第pos个元素
return OK;
}
时间复杂度为:O(ListLength(L))
插入操作
Status ListInsert_L(LinkList L,int pos,ElemType e)
{
p=L; j=0;
while(p&&j<pos-1) {p=p->next; ++j;} // 寻找第pos-1个结点
if(!p||j>pos-1) return ERROR; // pos小于1或者大于表长
s=(LinkList)malloc(sizeof(LNode)); // 生成新结点
s->data=e; s->next=p->next; //插入L中
p->next=s;
return OK;
}
时间复杂度为:O(ListLength(L))
删除操作
Status ListDelete_L(LinkList L,int pos,ElemType &e) {
p=L; j=0;
while(p&&j<pos-1) {p=p->next; ++j;} // 寻找第pos-1个结点
if(!(p->next)||j>pos-1) return ERROR; // 删除位置不合理
q=p->next; p->next=q->next; // 删除并释放结点
e=q->data; free(q);
return OK;
}
时间复杂度为:O(ListLength(L))