一、线性表
1.1线性表的顺讯存储
线性表的顺序存储结构指的是用一段地址连续的存储单元依次存储线性表的数据元素。
int GetElem(sqlist L, int i, ElemType e){ //获取元素
if(i<1||i>L.length){
return 0;
}
e=L.data[i-1];
return 1;
}
插入算法思路:
1.如果插入的位置不合理,抛出异常。
2.如果线性表的大小大于等于数组长度,则抛出异常或动态增加容量。
3.从最后一个元素开始向前遍历到第i个位置,分别将他们向后移动一个位置。
4.将要插入元素插入位置i处。
5.表长+1。
int ListInsert(sqlist L, int i, ElemType e){
int k;
if(i<1||i>L.length+1){ //插入位置不合理
return 0;
}
for(k=L.length-1;k>i-1;k--){
L.data[k+1]=L.data[k]; //元素后移一位
}
L.data[i-1]=e; //将新元素插入
L.length++; //表长+1
return 1;
}
删除算法思路:
1.如果删除位置不合理,抛出异常。
2.取出删除元素。
3.从删除元素开始遍历到最后一个元素位置,分别将他们向前移动一个位置。
4.表长-1。
int ListDelete(sqlist L, int i, ElemType e){
int k;
if(i<1||i>L.length){ //插入位置不合理
return 0;
}
i--; //将顺序表的逻辑顺序转化为物理顺序
e=L.data[i];
for(k=i;k<L.length-1;k++){
L.data[k]=L.data[k+1]; //元素位置前移
}
L.length--; //表长-1
return 1;
}
线性表顺序存储的优缺点:
优点:无须为表示表中的元素之间的逻辑关系而增加额外的存储空间;可以快速的存取表中任一位置的元素。
缺点:插入和删除操作需要移动大量的元素;当线性表长度变化较大时,难以确定存储空间的容量;造成存储空间的“碎片”。
1.2线性表的链式存储结构
n个结点(ai的存储映像)链结成一个链表,即为线性表(a1,a2,...,an)的链式存储结构,链表每个结点中只包含一个指针域,所以叫做单链表。链表中第一个结点的存储位置叫做头指针。为了更加方便的操作链表,会在单链表的第一个结点前设一个结点,叫做头结点。int GetElem(LinkList L, int i, ElemTye e){
int k=1; //k为计数器
LinkList p; //声明结点p
p=L->next; //p指向链表L的第一个结点
while(p&&k<i){
p=p->next; //p指向下一个结点
k++;
}
if(!p||k>i){
return 0;
}
e=p->data; //取出第i个元素的值
}
单链表第i个数据插入结点的算法:
1.声明结点p指向链表的第一个结点,初始化j从0开始。
2.当j<i-1时,遍历链表,p指针后移,指向下一个结点,j累加1。
3.若链表末尾p为空,则说明第i个元素不存在。
4.否则查找成功,在系统内生成一个空结点。
5.将元素e的值赋给s->data。
6.单链表插入语句s->next=p->next;p->next=s。
7.返回成功。
int ListInsert(LinkList L, int i, ElemTye e){
int j=0; //计数器
LinkList p=L,s;
while(j<i-1&&p){
j++;
p=p->next;
}
if(!p||j>i-1){
return 0;
}
s=(LinkList)malloc(sizeof(node)); //生成新结点
s->data=e;
s->next=p->next; //将p的后继结点赋给s的后继
p->next=s; //将s的值赋给p的后继
return 1;
}
单链表第i个数据删除结点的算法:
1.声明p结点指向链表的第一个结点,初始化j从0开始。
2.当j<i-1时,遍历链表,p指针后移,指向下一个结点,j累加1。
3.若链表末尾p为空,则说明第i个元素不存在。
4.否则查找成功,将要删除的结点p->next赋值给q。
5.单链表的删除语句p->next=q->next。
6.将q结点的数据赋值给e。
7.释放q。
8.返回成功。
int ListDelete(LinkList L, int i, ElemTye e){
int j=0; //计数器
LinkList p=L,q;
while(p&&j<i-1){
j++;
p=p->next;
}
if(!p||j>i-1){
return 0;
}
q=p->next; //将p的后继赋值给q
p->next=q->next; //将q的后继赋值给p的后继
e=q->data; //将q结点的值赋值给e
free(q); //释放q
return 1;
}
线性表顺序存储和链式存储对比:
1.若线性表需要频繁查找,很少进行插入和删除操作,适合采用顺序存储,反之使用链式存储。
2.当线性表的元素个数变化较大或者不知道有多大,适合采用链式存储,这样无需考虑存储空间的大小,反之若是事先知道线性表的大概长度适合顺序存储。