数据结构与算法2—— 线性链式存储
线性链式存储:
包含两部分:1.存储的单个元素
2.指针,指向下一个的地址
typedef struct() { ElementType Data; struct Node *Next; }List ; List L,Ptrl;
Ps:算法应保证具有可移植性,(ElementType)
表长函数,相比顺序数组存储复杂,需要遍历所有元素
定义一个新指针,始终指向当前的这个链表。
int length(List *Ptrl) { int i=0; List *p=Ptrl; while(p!=NULL) { p=p->Next; //通过指针实现了链表的链接 i++:} return i; }
下面进行查找数据,有两种查询方式,一种按第几个元素查找,一种按数据值查找。
按第几个元素查找: List *FindKth(int K,List *Ptrl) { List *p=Ptrl; int i=1; while(p!=Null && i<K) { p=p->Next; i++; } if(i==K) return p; else return NULL; }
K有查找范围,处理特殊情况时候:1. K<1 ,直接执行return NULL
2.K>链表长度的时候 此时p=Null,也是return NULL
3.因此不可以直接 return p;
按数据值查询:
List *FindKth(List *Ptrl,ElementType x)
{
List *p=Ptrl;
while(p!=NULL && p->Data!=x)
p=p->Next;
return p;
}
由于没有类似的K值的限制,可以直接return p
插入数据,在第i个位置插入数据时,相当于改变i-1以后,注意代码顺序,
成功返回新的链表的首地址,有问题失败时返回NULL;
List *add(ElementType x,List *Ptrl,int i)
{ List *p,*s;
if(i==1)
{
s=(List *)malloc(sizeof(List));
s->Data=x; //构造数据
s->Next=Ptrl;
return s; //由于插入在第一个位置,更新了链表首地址
}
p=FindKth(i-1,Ptrl)
if(p==Null) {printf("参数i错误");return NULL;}
else {
s=(List *)malloc(sizeof(List));
s->Data=x; //构造数据
s->Next=p->Next;
p->Next=s;
return Ptrl;
}
}
删除数据,最大的难点在于一定要释放被删除的数据,否则会造成内存泄漏
List *Delete(List *Ptrl,int i)
{
List *p,*s;
if(i==1)
{
s=Ptrl;
Ptrl=Ptrl->Next;
free(s);
return Ptrl;
}
p=FindKth(i-1,Ptrl);
if(p==NULL)
{printf("第%d个结点不存在,i-1"); return NULL;}
else if(p->Next==NULL)
{printf("第%d个结点不存在,i"); return NULL;} //删除的数据超出链表长度
else
{
s=p->next;
p->next=s->next;
free(s); 释放地址
return Ptrl;
}
}
两者都要单独考虑插入/删除第一个元素的情况,因为改变了首地址。