很久没写博客了,最近也比较忙~哎,天生ds命。今天一个学妹问链表相关的知识,借此之际正好总结一下链表的基本操作。
1、基本介绍:
链表是一种线性表,逻辑组织形式是一维的。链表的物理存储结构式用一组任意地址的内存单元,不是像顺序表那样占用一串连续的内存单元。
2、基本操作:(以C语言为例)
使用链表首先要建立一个结构体,其基本由数据域和指针域组成。通常还有一个“表头”,用来存放第一个节点的地址,本身不带数据。最后一个节点指针域一般为NULL。
节点描述如下:
typedef struct node{
ElemTyep data; //这里用ElemType指代任何类型
struct node *next;
}LNode,*LinkList;
这里注意一点就好了: LNode *L 和 LinkList L 这两句话是等价的。
创建链表:
LinkList createLinkList(int n){
LinkList p,r,list=null;
ElemType e;
int i;
for(i=1;i<=n;i++){
p=(LinkList)malloc(sizeof(LNode));
p->data=e;
p->next=null;
if(!list)
list=p;
else
r->next=p;
r=p;
}
return list;
}
这里list为头指针,最后用来返回。r用来指向结尾节点。
链表插入:(向q节点后面插入节点)
void insertList(LinkList *list,LinkList q,ElemType e){
LinkList p;
p=(LinkList)malloc(sizeof(LNode));
p->data=e;
if(!*list){
*list=p;
p->next=null;
}
else{
p->next=q->next;
q->next=p;
}
}
这里注意的是函数中的参数 LinkList *list ,它是指向LinkList类型的指针,也就是指向LNode类型的指针的指针。这是因为函数中要对list,也就是表头指针进行修改,当调用该函数时,实参应该为&list,而不是list。因此必须采用指针参数传递的方法,否则无法再被调函数中修改主函数中定义的变量的内容。
删除节点:
从非空链表中删除q节点要考虑不同的情况,大致分三类。q节点为第一个节点;q节点前驱节点已知;q节点前驱节点未知。
前两种可综合如下:
void delLink(LinkList *list,LinkList r,LinkList q){
if(q==*list)
*list=q->next;
else
r->next=q->next;
free(q);
}
后一种情况,需要先遍历链表找到q节点才行。
void delLink1(LinkList *list,LinkList q){
LinkList r;
if(q==*list){
*list=q->next;
free(q);
}
else{
for(r=*list;r->next!=q;r=r->next);
if(r->next!=null){
r->next=q->next;
free(q);
}
}
}
最后销毁链表:
在链表使用完后,最好销毁它,释放出其所占内存,防止内存泄露造成的麻烦。
void destroyLinkList(LinkList *list){
LinkList p,q;
p=*list;
while(p){
q=p->next;
free(p);
p=q;
}
*list=null;
}
先写到这里吧,目前觉得链表基础操作就这么些东西吧。如果有遗漏欢迎提出。