线性表(liner list)
线性表的顺序存储及操作实现
所谓顺序存储就是把线性表的各元素依次顺序地存放倒计算机内存中的一组地址连续的存储单元。采用顺序存储的线性表又叫顺序表。
顺序表是一种随机存取的存储结构。
顺序表的操作实现:
#define maxlen 100
tpyedef struct
{
datatype data[maxlen];
int length;
} listtp;
listtp L;
1、初始化
void INITLIST(listtp &L)
{
L.length=0;
}
2、求线性表的长度
int LISTLEN(listtp &L)
{
return L.length;
}
3、查找元素
int LOCALELEM(listtp &L,datatype x, int i)
{
for(i=0;i<L.length;i++)
{
if(L.data[i]==x)
return ++i;
}
return 0;
}
4、插入元素
void INSERTELEM(listtp &L,datatype x,int i)
{
int j;
if(i<1||i>L.length+1)
printf("infeasible/n");
else if(L.length>=maxlen)
printf("overflow/n");
else
{
for(j=L.length-1;j>=i-1;j--)
L.data[j+1]=L.data[j];
L.data[i-1]=x;
L.length++;
}
}
5、删除元素
void DELELEM(listtp &L,int i)
{
int j;
if(i<1||i>L.length+1)
printf("infeasible/n");
else if(L.length==0)
printf("Empty List/n");
else
{
for(j=i;j<=L.length-1;j++)
L.data[j-1]=L.data[j];
L.length--;
}
}
顺序存储适用于很少或根本不作插入、删除操作或只在表的端点处进行插入、删除等情况。
线性表的链式存储及操作实现
所谓链式存储就是逻辑上相邻的两个节点在存储位置上不相邻。采用链式存储结构的线性表称为链表。
按链接的方式,链表分为:单链表、双向链表、循环链表。
按实现的方式,链表分为:静态链表和动态链表。
typedef struct lnode
{
datatype data;
struct lnode *next;
} linklist;
linklist *head;
单链表的基本操作:
1、建立链表
linklist *INITLIST_L(linklist *head,int n)
{
linklist *p;
int i;
L=malloc(sizeof(linklist));
head->next=NULL;
for(i=n-1;i>0;i--)
{
p=malloc(sizeof(linklist));
scanf(&p->data);
p->next=head->next;
head->next=p;
}
return L;
}
2、按给定值查找元素
linklist *LOCALLIST(linklist *head,datatype x)
{
linklist *p;
p=head;
while(p&&p->data!=x)
{
p=p->next;
}
return p;
}
3、插入
(1)后插
INSERTAFTER_L(linklist *s,datatype x)
{
linklist *p;
p=malloc(sizeof(linklist));
p->data=x;
p->next=s->next;
s->next=p;
}
(2)前插
INSERTFORE_L(linklist *head,linklist *s,datatype x)
{
linklistx *p,*q;
p=malloc(sizeof(linklist));
p->data=x;
q=head;
while(q->next!=s)
{
q=q->next;
}
q->next=p;
p->next=s;
}
4、删除
DELELEM_L(linklist *head,linklist *s)
{
linklist *p;
p=head;
while(p->next!=s)
{
p=p->next;
}
p->next=s->next;
free(s);
}
循环链表
单链表最后一个节点的指针域指向头节点,这时整个链表就形成一个环,称这种链式存储结构为循环链表。
操作与单链表基本相同。
双向链表
节点中除数据域外,既含有指向直接前趋的指针域prior,又含有直接后继的指针域next。
typedef struct dlnode
{
datatype data;
struct dlnode *prior;
struct dlnode *next;
} dlinklist;
1、双向链表前插
INSERTFORE_DL(dlinklist *s,datatype x)
{
dlinklist *p;
p=malloc(sizeof(dlinklist));
p->data=x;
s->prior->next=p;
p->prior=s->prior;
p->next=s;
s->prior=p;
}
2、双向链表删除
DELELEM_DL(dlinklist *s)
{
s->next->prior=s->prior;
s->prior->next=s->next;
free(s);
}
顺序表与链表的比较
1、从存储空间利用率角度出发
顺序表的存储空间是静态分配的,可能过大,浪费空间,可能过小,产生溢出。
链表的存储空间是按需动态分配的,只要内存中有可分配空间,就不会产生溢出。
所以,当线性表的长度变化不大,且能预先估计出存储容量大小时,为了节省存储空间(链表中指针域需占额外存储空间)宜采用顺序存储结构。
2、从时间效率角度考虑
顺序表是随机存储结构,时间复杂度为O(1),而链表中每个节点存取都必须从头指针起,顺链扫描才能实现。
因此,当对线性表进行的主要操作是查找,而很少进行插入删除操作时,宜采用顺序表存储结构。当对线性表进行插入和删除操作频繁时,宜采用链表作为存储结构。