一、链表的概念:链表是一种常见而重要的动态储存分布的数据结构。链表像车链子一样,它由若干个同结构类型的“结点”依次串接而成的。
链表对比数组最大的特点是每个数据单元都是动态分配的,节省内存空间,且操作灵活。
关于动态分配相关的函数
void *malloc(unsigned size)
功能:在内存的动态存贮区中分配一块长度为size的连续空间。
返回值:指针,存放被分配内存的起始地址。若未申请到空间,则返回 NULL( 0 )。
例如:(int *) malloc(sizeof(int))
(struct student *) malloc(sizeof(struct student))
void free(void *ptr)
功能:释放由malloc()申请的动态内存空间,ptr存放该空间的首地址。
例如:free(p);
链表用法:链表变量一般用指针head表示,用来存放链表的首结点的地址;链表中每个结点由结构数据成员数据部分和下一个结点的地址部分组成,即每个结点都指向下一个结点。
通常使用结构来定义单向链表结点的数据
例如:
二、单向链表的常用操作
- 链表的建立
- 链表的遍历
- 结点的插入
- 结点的删除
1、链表的建立:主要有两种头部和尾部插入法
p->next = NULL;
if(head == NULL)
head = p; //尾部插入法
else
tail->next = p;
tail = p;
p->next = NULL;
if(head == NULL)
head = p; //头部插入法
else
p->next=head;
head=p;
2、链表的遍历
for(ptr=head;ptr!=NULL;ptr=ptr->next)
printf(“%d%s%d\n”,ptr->num,ptr->name,ptr->score);
3、结点插入
先判断要插入结点位于链表的哪个位置,插入要先连后断。
先连: s->next = ptr->next;
后断: ptr->next = s;
例如:
if(head==NULL){
head=ptr; //插入的结点成为头结点
head->next=NULL;
}
else{ //原链表不为空的插入
while((ptr->num>ptr2->num)&&(ptr2->next!=NULL)){
ptr1=ptr2; //ptr1、ptr2各后移一个结点
ptr2=ptr2->next;
}
if(ptr->num<=ptr->num){ //在ptr1与ptr2之间插入结点
if(head==ptr2) head=ptr;
else ptr1->next=ptr;
ptr->next=ptr2;
}
else{ //插入结点成为尾部
ptr2->next=ptr;
ptr->next=NULL;
}
}
- 结点删除
结点删除也要判断结点的位置,先接后删。即当ptr2为要删掉的结点,先将ptr1指向的结点与ptr2指向的结点的下一个结点连上,并将ptr2的储存空间释放。
ptr1->next=ptr2->next;
free(ptr2);
例:
//当要删除的结点为表头时
ptr2=head;
head=head->next;
free(ptr2);
//链表为空
if(head==NULL)
return NULL;
//ptr2所指结点是要删除的结点
ptr1=head;
ptr2=head->next;
if(ptr2->num==num){
ptr1->next=ptr2->next;
free(ptr2);}
本内容转载至
原文链接:http://blog.qmgua.com/?id=134