什么是链表
链表一种线性的数据结构,通过指针将一个个零散的内存块连接起来,链表的每个内存块称为结点。结构体指针在这里得到了充分的利用。
为什么要使用链表
链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
链表和数组的区别和实现
数组(有序) | 存放数据的地址连续,可对其中某个数据进行修改或查询,但如果要对数组进行增添或删减,是非常麻烦的。数组地址连续,若删除某一位,需让后面的所有数据往前挪;若增添某一位,数组大小已经确定,将会造成数组越界。 |
链表(无序) | 存放数据的地址随意,通常运用结构体指针,即第一个指针存放第二个数据的地址,第二个指针存放第三个数据的地址,以此类推。若删除某一位,则只需将前一位指针指向删除位的下一位即可;若增添某一位,则只需将前一位指向添位,增添位指向下一位即可。 |
数组:
链表:
这里t1.next保存的是t2的地址,t2.next保存的是t3的地址,t1为链表头,所以通过t1能找到后面的数。
可见两者的编译结果相同。
对链表代码进行函数封装化:
#include <stdio.h>
struct Test
{
int Data;
struct Test *next;
};
void printLink(struct Test *head)
{
struct Test *point;//定义一个指针
point = head;//指向参数的地址
while(point!=NULL)//如果指针不指向空地址
{
printf("%d ",point->Data);//输出地址对应数据
point = point->next;//将下一个地址赋给point
}
putchar('\n');
}
int main()
{
struct Test t1={1,NULL};
struct Test t2={1,NULL};
struct Test t3={3,NULL};
struct Test t4={4,NULL};
struct Test t5={5,NULL};
t1.next=&t2;
t2.next=&t3;
t3.next=&t4;
t4.next=&t5;
puts("use t1 to print three nums");
printLink(&t1);
return 0;
}