什么是链表(优缺点)
链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成。
结点包括两个部分:(1)存储数据元素的数据域(内存空间),(2)存储指向下一个结点地址的指针域。
相对于线性表顺序结构,操作复杂。
优点:
(1)插入和删除速度快,保留原有的物理顺序,在插入或者删除一个元素的时候,只需要改变指针指向即可。
(2)没有空间限制,存储元素无上限,只与内存空间大小有关.
(3)动态分配内存空间,不用事先开辟内存
(4)是内存的利用率变高
缺点:
(1)占用额外的空间以存储指针,比较浪费空间,不连续存储,malloc函数开辟空间碎片比较多)
(2)查找速度比较慢,因为在查找时,需要循环链表。
静态创建链表
创建 计数 查找
#include<stdio.h>
struct Test
{
int data;
struct Test *next;
};
int noodnum(struct Test *head)
{
int cnt;
while(head != NULL){
cnt++;
head = head->next;
}
return cnt;
}
int search(struct Test *head,int a)
{
while(head != NULL){
if(a == head->data){
return 1;
}
head = head->next;
}
return 0;
}
void print(struct Test *head)
{
struct Test *point;
point = head;
while(point != NULL){
printf("%d ",point->data);
point = point->next;
}
putchar('\n');
}
int main()
{
int a[3] = {1,2,3};
int i;
for(i=0;i<sizeof(a)/sizeof(a[0]);i++){
printf("%d ",a[i]);
}
putchar('\n');
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
t1.next = &t2;
t2.next = &t3;
printf("%d %d %d\n",t1.data,t2.data,t3.data);
print(&t1);
int cnt = noodnum(&t1);
printf("cnt:%d\n",cnt);
int a1;
printf("Input:");
scanf("%d",&a1);
int ret = search(&t1,a1);
if(ret == 1){
printf("有%d\n",a1);
}else if(ret == 0){
printf("没有%d\n",a1);
}
return 0;
}
增
#include<stdio.h>
struct Test
{
int data;
struct Test *next;
};
void print(struct Test *head)
{
struct Test *p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test *insertFormBehind(struct Test *head,int data,struct Test *new)// 尾插法
{
struct Test *p = head;
while(p != NULL){
if(p->data == data){
new->next = p->next;
p->next = new;
printf("插入成功\n");
return head;
}
p = p->next;
}
printf("插入失败\n");
return head;
}
struct Test *insertFormfront(struct Test *head,int data,struct Test *new)// 头插法
{
struct Test *p = head;
if(p->data == data)
{
new->next = head;
printf("插入成功\n");
return new;
}
while(p->next != NULL){
if(p->next->data == data){
new->next = p->next;
p->next = new;
printf("插入成功\n");
return head;
}
p = p->next;
}
printf("插入失败\n");
return head;
}
int main()
{
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
t1.next = &t2;
t2.next = &t3;
struct Test *head = &t1;
// printf("%d %d %d\n",t1.data,t2.data,t3.data);
print(head);
struct Test new = {100,NULL};
head = insertFormBehind(head,3,&new);
print(head);
struct Test new2 = {1000,NULL};
head = insertFormfront(head,1,&new2);
print(head);
return 0;
}
删 改
#include<stdio.h>
struct Test
{
int data;
struct Test *next;
};
void print(struct Test *head)
{
struct Test *p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test *deletenode(struct Test *head,int data)
{
struct Test *p = head;
if(p->data == data){
p = p->next;
return p;
}
while(p->next != NULL){
if(p->next->data == data){
p->next = p->next->next;
return head;
}
p = p->next;
}
return head;
}
struct Test *gainode(struct Test *head,int data,int newdata)
{
struct Test *p = head;
if(p->data == data){
p->data = newdata;
return p;
}
while(p->next != NULL){
if(p->next->data == data){
p->data = newdata;
return head;
}
p = p->next;
}
return head;
}
动态创建链表
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test *next;
};
void print(struct Test *head)
{
struct Test *p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test *insretforhead(struct Test *head ,struct Test *new)
{
if(head == NULL){
head = new;
}else{
new->next = head;
head = new;
}
return head;
}
struct Test *insretforbehind(struct Test *head ,struct Test *new)
{
struct Test *p = head;
if(head == NULL){
head = new;
return head;
}
while(p->next != NULL){
p = p->next;
}
p->next = new;
return head;
}
struct Test *createlink(struct Test *head)
{
struct Test *new;
while(1){
new = (struct Test *)malloc(sizeof(struct Test));
printf("Input:\n");
scanf("%d",&(new->data));
if(new->data == 0){
printf("0 quit\n");
return head;
}
head = insretforbehind(head,new);
}
}
int main()
{
struct Test *head = NULL;
head = createlink(head);
print(head);
struct Test t1 = {100,NULL};
head = insretforhead(head,&t1);
print(head);
struct Test t2 = {100,NULL};
head = insretforbehind(head,&t2);
print(head);
return 0;
}
学生成绩管理
链表A,每个节点存放一个新的链表B1,B2,B3,B4,B5的头结点。
场景:一个年级,相当链表A
该年级5个班,每个班5个人,相当于链表B1–B5
做一个学生成绩管理系统
学生成绩有语文 数学 英语
功能: 录入成绩 找三科总分的最高分 最低分 算出平均分
#include <stdlib.h>
#include <stdio.h>
struct Class
{
int num;
struct Stu *head;
struct Class *next;
};
struct Stu
{
int num;
char *name;
int Chinese;
int Math;
int English;
int sum;
struct Stu *next;
};
struct Stu *insertStu(struct Stu *head,struct Stu *new)
{
struct Stu *p = head;
if(head == NULL){
head = new;
return head;
}
while(p->next != NULL){
p = p->next;
}
p->next = new;
return head;
}
struct Stu *createStu(struct Stu *head,int a,int data)
{
struct Stu *p = NULL;
int i;
for(i=1;i<data+1;i++){
p = (struct Stu *)malloc(sizeof(struct Stu));
printf("%d年级第%d个学生的名字",a,i);
p->name = (char *)malloc(128);
scanf("%s",p->name);
printf("%d年级第%d个学生的语文成绩",a,i);
scanf("%d",&(p->Chinese));
printf("%d年级第%d个学生的数学成绩",a,i);
scanf("%d",&(p->Math));
printf("%d年级第%d个学生的英语成绩",a,i);
scanf("%d",&(p->English));
p->num = data;
p->sum = p->Chinese + p->Math + p->English;
head = insertStu(head,p);
}
return head;
}
struct Class *insretClass(struct Class *head,struct Class *new)
{
struct Class *p = head;
if(head == NULL){
head = new;
return head;
}
while(p->next != NULL){
p = p->next;
}
p->next = new;
return head;
}
struct Class *createClass(struct Class *head)
{
struct Class *new = NULL;
struct Stu *Head = NULL;
int i;
int data1;
printf("输入年级数:\n");
scanf("%d",&data1);
int data2;
printf("请输入学生数\n");
scanf("%d",&data2);
for(i=1;i<data1+1;i++){
new = (struct Class *)malloc(sizeof(struct Class));
Head = createStu(Head,i,data2);
new->head = Head;
new->num = data1;
head = insretClass(head,new);
}
return head;
}
void max(struct Class *head)
{
struct Class *p1 = head;
struct Stu *p2 = (struct Stu *)malloc(sizeof(struct Stu));
p2 = p1->head;
int data1 = p1->num;
int data2 = p2->num;
int i;
int j;
int max = 0;
for(i=1;i<data1+1;i++){
for(j=1;j<data2+1;j++){
if(p2->sum > max){
max = p2->sum;
}
p2 = p2->next;
}
p1 = p1->next;
}
printf("max:%d\n",max);
}
void min(struct Class *head)
{
struct Class *p1 = head;
struct Stu *p2 = (struct Stu *)malloc(sizeof(struct Stu));
p2 = p1->head;
int data1 = p1->num;
int data2 = p2->num;
int i;
int j;
int min = 10000;
for(i=1;i<data1+1;i++){
for(j=1;j<data2+1;j++){
if(p2->sum < min){
min = p2->sum;
}
p2 = p2->next;
}
p1 = p1->next;
}
printf("min:%d\n",min);
}
void avg(struct Class *head)
{
struct Class *p1 = head;
struct Stu *p2 = (struct Stu *)malloc(sizeof(struct Stu));
p2 = p1->head;
int data1 = p1->num;
int data2 = p2->num;
int i;
int j;
int sum = 0;
for(i=1;i<data1+1;i++){
for(j=1;j<data2+1;j++){
sum = sum + p2->sum;
p2 = p2->next;
}
p1 = p1->next;
}
float avg = (float)sum/(data1*data2);
printf("avg:%.2f\n",avg);
}
void print(struct Class *head)
{
struct Class *p1 = head;
struct Stu *p2 = (struct Stu *)malloc(sizeof(struct Stu));
p2 = p1->head;
int data1 = p1->num;
int data2 = p2->num;
int i;
int j;
int min = 10000;
for(i=1;i<data1+1;i++){
for(j=1;j<data2+1;j++){
printf("%d班第%d个人:名字:%s 语文:%d 数学:%d 英语:%d\n",i,j,p2->name,p2->Chinese,p2->Math,p2->English);
p2 = p2->next;
}
p1 = p1->next;
}
}
int main()
{
struct Class *head;
head = createClass(head);
print(head);
max(head);
min(head);
avg(head);
return 0;
}