链表是数据之间的关系呈现逻辑线性,存储方式为链式存储的的一种数据存储方式,它具有一下几方面的特点:
1、每个元素之间的地址不相连:
在顺序表中,我们开辟空间往往采用数组的形式开辟,因此其每个元素在存储空间上都是连续存储的,但是由于顺序表中对元素进行插入和删除涉及大量元素的地址迁移,因此,我们引用了链表,链表由malloc(size)函数开辟空间,此处的size为我们定义的结构体的大小。
注意:我们在定义结构体时需要包括数据域(存储当前元素的数据),还需要包括地址域(存放下一个结构体元素的首地址),以便我们后续的访问。
2、大小是可以改变的
顺序表中,由于定义的数据空间为数组类型,因此在定义之初大小就已经确定,对后续添加元素会带来很多不便;
链表由于之间是依靠存放自身地址来进行连接,因此在添加或者删除元素时只需要将对应位置两边的元素断开,再将需要更改的元素接入即可(此处必须先将插入位置后面的元素地址存放到新元素的数据域才可将新元素地址存放进上一个元素,否则就会出现地址丢失的问题)
从理论上来说,只要内存足够大,链表的大小是可以无限增大的
当然,链表本身也存在一些缺点:
1、链表每次插入元素时都需要开辟新的空间
linklist *Create_LinkList()//创建表
{
linklist *head = (linklist *)malloc(sizeof(linklist));
if(NULL == head){
printf("创建失败\n");
return NULL;
}
head->data = -1;
head->next = NULL;
printf("创建成功\n");
return head;
}
void LinkList_Insert_Data(linklist *head, int data)//从表头插入数据
{
linklist *new = (linklist *)malloc(sizeof(linklist));
if(NULL == new){
printf("插入数据失败\n");
return;
}
new->data = data;
new->next = NULL;
new->next = head->next;
head->next = new;
}
void LinkList_Insert_Pos(linklist *head, int pos, data_t data)//按位置插入数据
{
int len = LinkList_length(head);
if(pos < 0 || pos > len){
printf("位置错误\n");
return;
}
linklist *new = (linklist *)malloc(sizeof(linklist));
if(NULL == new){
printf("插入数据失败\n");
return;
}
linklist *p = head;
while(pos--){
p = p->next;
}
new->next = p->next;
p->next = new;
new->data = data;
}
2、链表本身的查找和修改效率低下
链表所在空间由于本身为不连续空间,所以在遍历数组的时候无法向顺序表一样来通过下标来进行遍历。链表遍历往往需要通过计算链表长度,再通过地址访问来实现,以下是链表长度的实现:
int LinkList_length(linklist *head)//计算表长
{
linklist *p = head->next;
if(NULL == head->next){
printf("表长为0\n");
return 0;
}
int len = 0;
while(p){
p = p->next;
len++;
}
return len;
}
3、链表在清空元素时需要通过free()释放内存并将地址域数据置为NULL
void LinkList_Clearn(linklist *head)//清空链表
{
if(LinkList_Is_Empty(head)){
return;
printf("表为空\n");
}
linklist *p = head->next;
linklist *q = NULL;
int len = LinkList_length(head)+1, i = 0;
while(len--){
q = p;
p = p->next;
free(q);
q->next = NULL;
if(p->next == NULL){
free(p);
break;
}
}
head->next = NULL;
printf("表已清空\n");
return;
}
4、删除链表时需要先清空链表
void LinkList_Delete(linklist *head)//删除链表
{
LinkList_Clearn(head);
free(head);
head->next = NULL;
printf("表已删除\n");
}
以上即为本期内容,欢迎参考,指正!!!