线性表
重点:
- 线性表的逻辑结构
- 线性表的顺序存储结构
- 线性表的链式存储结构
- 一元多项式的表示及相加
定义:
线性表n(n>=0)的同质元素的有限数列,每个元素有唯一的前驱和后继。首元素只有后继,尾元素只有前驱,n为0时是空表,n叫做线性表的长度。
线性表的基本操作
- 初始化 InitList(&L)
- 销毁 DestroyList(&L)
- 清空 ClearList(&L)
- 判断空表 ListEmpty(L)
- 求长度 ListLength(L)
- 取i值 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())
- 复制 Copy(L,C) (L复制到C)
- 合并 Merge(A,B,C) (把A,B合并到C中)
顺序存储结构
所有数据类型相同,占用空间大小相同。查找数据方便,常用数组表示顺序存储结构。
数组特点(用数组表示的原因)
- 数组元素间连续
- 数组所有元素数据类型相同
由于线行表的长度可变,所需的最大存储空间随问题的不同而不同。下面是线性表的动态分配顺序存储结构
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配量
typedef struct{
ElemType *elem;//存储空间基址
int length; //当前长度
int listsize;//当前分配的存储容量
}SqList;
顺序表的插入操作
int Insertlist(Sqlist*L,int I,Elemtype x)
int j;
if(I<0||I>listlength(L))
{printf(“Error!”);
return FALSE;}
if(I>MAXNUM-1)
{printf(“overflow!”);
return FALSE;}
for(j=listlength(L)-1;j>=I;j–)
L->elem[j+1]=L->elem[j];
L->elem[j]=x;
L->length=L->length+1;
return TRUE;}
顺序表的删除操作
int Delete(Seqlist*L,int i,&e)
int j;
if(i<=0||i>Llstlength(L))
{printf(“Error!”);
return FAlSE;}
e=L->ele[i-1];
for(j=i-1;j<Listlength(L)-1;j++){
L->elem[j]=L->elem[j+1];
L->length–;
return TRUE;}
- 表长为n的顺序存储的线性表,当在任何位置上插入和删除相等时,插入一个元素所需移动元素平均个数为n/2,删除一个元素所需移动的平均个数为(n-1)/2.
顺序存储结构特点
- 顺序存储的线性表可以随机存取其中任意元素
- 数据元素最大个数需预先确定
- 需要预先确定最大个数
- 插入和删除效率低
- 存储空间不变扩充
链式存储结构
- 存储数据元素的值
- 存储各数据元素之间的逻辑顺序
- 将结点分为两部分:数据域(存储数据元素的值),指针域(下一个存储结点的位置)
- 只含一个指针域的链表称为单向链表
结点的描述与实现
- 带指针的结构体类型的描述
typedef struct Lnode{
ElemType Data;
struct Lnode *next:
}LNode;
结点的实现
malloc(),realloc(),sizeof(),free()
动态分配
s=(LNode*)malloc(sizeof(LNode))
动态分配
free(s)
结点赋值
LNodep;
p=(LNode)malloc(sizeof(LNode));
p->date=20;p->next=NULL;
常见指针操作
q=p;
q=p->next;
p=p->next;
q->next=p;
q->next=p->next;
单链表的初始化
int Initiate(slnodetype**h)
{if((*h=(slnodetype *)malloc(sizeof(slondetype)))=NULL)
return FALSE;
(*h)->next=NULL:
return TRUE;}
单链表插入
- 后插入
s=(slnodetype *)malloc(sizeof(slnodetype));
s->data=x;s->next=p->next;p->next=s;}
- 前插入
{q=head;
while(q->next!=p)q=q->next;
s=(slnodetype *)malloc(sizeof(slnodetype));
s->date=x;s->next=p;
q->next=s;}
建立非空链表
- 头插法
LNode *create_LinkList(void)
{
int date;
LNode *head, *p;
head=(LNode )malloc(sizeof(LNode));
head->next=NULL;
while(1)
{
scanf("%d",&data);
if(data==32767)break;
p=(LNode)malloc(sizeof(LNode));
p->next=head->next;head->next=p;
}
return(head);}
- 尾插入法
LNode *create_LinkList(Void)
{
int date;
LNode head,p,q;
head=p=(LNode)malloc(sizeof(LNode));
p->next=NULL;
while(1)
{
scanf("%d",&data);
if(data==32767)break;
q=(LNode)malloc(sizeof(LNode));
q->data=data;
q->next=p->next;p->next=q;p=q;
}
return(head);}
两段论
- 对象->next=前驱
- 前去->next=对象
小结
- 线性表的顺序存储结构中,插入和删除元素时,移动元素的个数与该元素的位置有关。
- 线性表读取元素的时间与大小无关,因为顺序存储逻辑相邻物理相邻,确定元素地址相同,读取时间相同。
- 顺序存储的线性表可以随机存储,逻辑相邻物理相邻,马上可以得到存取地址,既可以存数据,也可以随机取某个数据。
- 数据项是数据的最小单位。
- 线性表中所有结点类型相同
- 频繁进行插入或删除,应采用链式存储。
- 线性表中各元素之间关系是有序关系
- 双向链表的一个结点2个指针。
- 线性表的链式存储结构中,内存中可用存储单位可连续,可不连续。