链表的优点:
1.数据元素的个数可以自由扩充
2.插入,删除等操作不必移动数据,只需修改链表指针,修改效率较高
链表的缺点:
1.存储密度小
2.存储效率不高,必须采用顺序存取,即存取数据元素时,只能按链表的顺序进行访问
情景:设置一个链表存储n个的学生信息
在结构体中设置一个结构体指针
struct student
{
char name[21];
int id;
struct student *next;
};
为了后续声明结构体的方便,可使用typedef对其重命名
typedef:例如声明一个结构体,一般都是struct student a; 重命名之后只需要stu a;就完成了结构体的声明。
struct student
{
char name[21];
int id;
struct student *next;
};
typedef struct student stu;
链表的原理:
链表在主函数中的构建:
首先声明三个结构体指针:
stu *p,*head,*tail;
head用来标记头节点,tail用来标记尾节点,p如同进度条,可活动在任意节点
此时的指针都还是没有地址的空指针 ,因此我们需使用malloc函数为其分配内存
malloc:为指针动态分配内存,使用时需要用到stdlib.h头文件。
p=(struct student*)malloc(sizef(struct student));
由于此时链表为空,需要将head和tail都指向内存p,此时p为头节点,只负责标记,不需要填入内容
head=p;
tail=p;
head->next=NULL;
内容的输入:
for(int i=0;iname);
printf("请输入学号:");
scanf("%d",&p->id);
}
链表的延长:
tail->next=p;
tail=p;
tail->next=NULL;
链表的遍历:
p=head->next;
while(p!=NULL)
{
printf("姓名:%s 学号:%d\n",p->name,p->id);
p=p->next;
}
完整代码如下:
#include
#include
struct student
{
char name[21];
int id;
struct student *next;
};
typedef struct student stu;
int main()
{
int n;
printf("请输入学生人数:");
scanf("%d",&n);
stu *p,*head,*tail;
p=(struct student*)malloc(sizeof(struct student));
head=p;
tail=p;
head->next=NULL;
for(int i=0;iname);
printf("请输入学号:");
scanf("%d",&p->id);
tail->next=p;
tail=p;
tail->next=NULL;
}
p=head->next;
while(p!=NULL)
{
printf("姓名:%s 学号:%d\n",p->name,p->id);
p=p->next;
}
return 0;
}
运行样例如下:
情景:有一串已经从小到大排好的数2 3 4 5 8 9 10 18 26 32,现需要往这串数中插入6使其得到的新序列仍然符合从小到大排列,即2 3 4 5 6 8 9 10 18 26 32.
具体代码如下:
#include
#include
struct node
{
int data;
struct node *next;
};
int main()
{
int n;
int a;
printf("请输入数字个数:");
scanf("%d",&n);
struct node *head,*tail,*p,*num;
p=(struct node*)malloc(sizeof(struct node));
head=p;
tail=p;
head->next=NULL;
printf("请输入已有数字:");
for(int i=0;idata);
tail->next=p;
tail=p;
tail->next=NULL;
}
printf("请输入待插入的数;");
scanf("%d",&a);
num=(struct node*)malloc(sizeof(struct node));
num->data=a;
p=head;
while(p!=NULL)
{
if(p->next==NULL||p->next->data>num->data)
{
num->next=p->next;
p->next=num;
break;
}
p=p->next;
}
p=head->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
return 0;
}
关键点:
while(p!=NULL)
{
if(p->next==NULL||p->next->data>num->data)
{
num->next=p->next;
p->next=num;
break;
}
p=p->next;
}
运行结果:
链表的删除思路同链表的插入一样。