链表的优缺点和创建
链表的优点分为两点来看
空间性能
链表不需要为数据预先分配空间,当线性表的存储规模比较大时候,例如全国性的数据,可以采取链表创建,有或者是难以预估存储规模时,采取链表作为存储结构是最好的选择。
链表的存储密度小于1,所以链表的创建是比顺序表更加浪费内存,因为有一部分是用来存储指针域的。
时间性能
顺序表和链表的最大区别就是在插入,删除数据的时候,链表的时间复杂度是O(1),而顺序表的插入和删除都是O(n)。但是顺序表在改表值的时候是O(1)。对于频繁进行插入或者删除操作的线性表,应当采用链表。
创建链表
前插法
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;//结点的数据域
struct node *next;//结点的指针域
};
int main()
{
struct node *head,*p;
int i,n;
head = (struct node *)malloc(sizeof(struct node));//为头结点申请空间
head->next = NULL;//头结点指针域指向空
printf("请输入链表长度:");
scanf("%d",&n);//输入表长
for(i=1;i<=n;i++)
{
p = (struct node *)malloc(sizeof(struct node));//为新结点申请空间
scanf("%d",&p->data);//向新结点p的数据域中添加元素
p->next = head->next;
head->next = p;//头结点的指针域指向新结点
}
while(1)//遍历元素
{
printf("%d ",p->data);
if(p->next==NULL)
break;//如果是最后一个结点则跳出循环
p = p->next;//p指向下一个结点
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;//结点数据域
struct node *next;//结点指针域
};
int main()
{
struct node *head,*p,*r;
head = (struct node *)malloc(sizeof(struct node));//创建头结点
head->next = NULL;//头结点指针域指向空
r = head;//用r指针指向头结点
int i,n;
printf("请输入链表长度:");
scanf("%d",&n);//输入表长
for(i=1;i<=n;i++)
{
p = (struct node *)malloc(sizeof(struct node));//创建新结点
scanf("%d",&p->data);//向新结点添加元素
p->next = NULL;//新结点指针域指向空
r->next = p;//用r指针域指向新增结点
r = p;//用r指针指向新增结点
}
head = head->next;
while(1)//遍历链表元素
{
printf("%d ",head->data);
if(head->next==NULL)//遍历到最后一个元素时跳出循环
break;
head = head->next;//指向下一个结点
}
return 0;
}
这里便于后续理解,我画了一张图便于读者理解
下面我采用前插法来对链表进行操作
链表的查找
/*
note:这里head是头结点,我为了便于直接计算数,就一开始让其指向了首元结点。
*/
head = head -> next ;
int num = 1 ;
while(head != NULL && head->data != 5)
{
head = head -> next ;
num++ ;
}
printf("你查找的元素位置在第%d个位置\n",n+1-num);
链表的删除
head = head -> next ;
//单链表的删除 例如删除特定位置(第三个元素)
while (head && num <= 2)
{
head = head -> next ;
num ++ ;
}
printf("%d,你已经拿到你想要的数据了\n",head->data) ;
// 拿到数据之后,才做删除的操作。
head -> next = replace ; // 设置一个中间变量存储想要被删除的元素
head -> next = replace -> next ; // 将地址变成下一个
delete(replace) ;
// 这里的释放空间读者可以自行尝试一下,毕竟我不是主C的。
链表的查找
head = head -> next ;
while (head && num < 2)
{
head = head -> next ;
num++;
}
printf("你想拿到的数据是%d",head -> data);
以上是我对C语言链表的理解,至于双向链表,循环链表读者可自行尝试