2.1.3 线性表的链式结构实现
线性表的顺序存储结构的物理地址是相邻的,而线性表的链式存储结构的物理地址可以不相邻,通过“链”建立起数据元素之间的逻辑关系。
typedef struct LNode *List;
struct LNode{
int Data;
List Next;
};
求表长
int Length(List PtrL){
List p=PtrL;
int j=0;
while(p){
p=p->Next;
j++;
}
return j;
}
查找
问题描述: 按照元素的序号或者值查找,并返回查找结果,查到返回地址,查不到返回空。
- 按序号查找
List FindKth(List PtrL,int K){//按序号查找
List p;
int i=1;
while(p!=NULL && i<K){
p=p->Next;
i++;
}
if(i==K)
return p;//找到返回地址
else
return NULL;//没找到,返回空
}
- 按值查找
List Find(List PtrL,int X){
List p;
while(p!=NULL && p->Data!=X){
p=p->Next;
}
// if(p)
// return p;
// else
// return NULL;
return p;
}
插入
问题描述: 在第 i − 1 i-1 i−1 个结点后插入一个值为 X X X的新结点,其中 i=1,2,…,n-1
思路:
- 先构造一个新结点,用 s s s 指向
- 再找到链表的第 i − 1 i-1 i−1 个结点,用 p p p 指向
- 修改地址,插入结点(p结点后插入s结点)
List Insert(List PtrL,int i,int X){
List p,s;
if(i==1){
s=(List)malloc(sizeof(struct LNode));
s->Data=X;
s->Next=PtrL;
return s;
}else{
p=Find(PtrL,i-1);
if(p==NULL){//第i-1个结点不存在,无谈后续插入
printf("参数i错\n");
return NULL;
}
else{
s=(List)malloc(sizeof(struct LNode));
s->Data=X;
s->Next=p->Next;
p->Next=s;
return PtrL;
}
}
}
删除
问题描述: 删除链表上第 i i i 个位置的结点,其中 i=1,2,…,n
思路:
- 先找到链表的目标结点——第i个结点,用s指向
- 再找到链表的第i-1个结点,用p指向
- 修改地址,删除s所指向结点
- 释放s结点
List Delete(List PtrL,int i){
List p,s;
if(i==1){
s=PtrL;
if(PtrL==NULL)
return NULL;//不用释放了吗?
else
PtrL=PtrL->Next;
free(s);
return PtrL;
}
p=FindKth(PtrL,i-1);
if(!p){
printf("第%d个结点不存在!",i-1);
return NULL;
}
if(p->Next==NULL){
printf("第%d个结点不存在!",i);
return NULL;
}
s=p->Next;
p->Next==s->Next;
free(s);
return PtrL;
}
总结: 链式存储结构在插入和删除操作时,对第一个位置的操作需要额外处理。插入时,结点s是一个新申请组装的结点;删除时,结点s是一个结点类型的指针。
ps: 初学数据结构,如有错误,敬请指点!