struct lnode是什么结构类型_第十讲:C语言基础之结构体和共用体(链表)

本文约4900字,主要讲了结构体和共用体-链表(建立动态链表、对链表的删除操作、对链表的插入操作)。

带你进入C语言的世界,入门C语言,后边将持续更新。可以收藏学习。想了解结构体和共用体,内容接上一节。包括指向结构体类型数据的指针、结构指针变量作函数参数和动态存储分配等,请点击该处跳转阅读。

本文全干货,新手必备,感谢你的阅读,祝你学有所成,生活愉快!


链表是一种常见的重要的数据结构,是动态地进行存储分配的一种结构。

链表的组成:

头指针:存放一个地址,该地址指向第一个元素

结点:用户需要的实际数据和链接节点的指针

906f5039ee4bf652af2decbefc0ac054.png

一、建立动态链表

所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。

例题:homework

作业:根据下面的分析写一函数建立一个含有学生(学号,成绩)数据的单向动态链表。(约定:我们约定学号不会为零,如果输入的学号为0,则表示建立链表的过程完成,该结点不应连接到链表中。)

34c544e51e1e2de309491aea4f2db25a.png
62082016f7a21e62a8f2d65c8865f0df.png

如果输入的p1->num不等于0,则输入的是第一个结点数据(n=1),令head=p1,即把p1的值赋给head,也就是使head也指向新开辟的结点p1所指向的新开辟的结点就成为链表中第一个结点。

9983974c36880c0abbebf47d81fbad24.png

再开辟一个结点并使p1指向它,并输入该结点的数据。

在第三次循环中,由于n=3(n≠1),又将p1的值赋给p2->next,也就是将第3个结点连接到第2个结点之后,并使p2=p1,使p2指向最后一个结点。

c4c19d1bc9a20d881ff394f50ffa3b96.png

再开辟一个新结点,并使p1指向它,输入该结点的数据。由于p1->num的值为0,不再执行循环,此新结点不应被连接到链表中。

将NULL赋给p2->next。

建立链表过程至此结束,p1最后所指的结点未链入链表中,第三个结点的next成员的值为NULL,它不指向任何结点。

链表的输出:

首先要知道链表第一个结点的地址,也就是要知道head的值。然后设一个指针变量p,先指向第一个结点,输出p所指的结点,然后使p后移一个结点,再输出,直到链表的尾结点。如此我们得到这样的流程图:

bcb9ef25f8db7366b4760b90f6b1f853.png

二、对链表的删除操作

从一个动态链表中删去一个结点,并不是真正从内存中把它抹掉,而是把它从链表中分离开来,只要撤销原来的链接关系即可。

3bc17d1b0bc4eb51a14d526265e6695a.png

例题:写一函数以删除动态链表中指定的结 点。

解题思路:

一、从p指向的第一个结点开始,检查该结点中的num值是否等于输入的要求删除的那个学号。

二、如果相等就将该结点删除,如不相等,就将p后移一个结点,再如此进行下去,直到遇到表尾为止。

三、可以设两个指针变量p1和p2,先使p1指向第一个结点 。

四、如果要删除的不是第一个结点,则使p1后移指向下一个结点(将p1->next赋给p1),在此之前应将p1的值赋给p2 ,使p2指向刚才检查过的那个结点。

五、将以上几点我们综合得出算法流程图:

bab525f15f1f4acf36d605533e30032e.png

#include

#include

#include

#define LEN sizeof(struct student) // student结构的大小

struct student *creat(); //创建链表

struct student *del( struct student *head, int num); //del函数用于删除结点, *head即链表

//的头指针, num是要删除的结点num。

void print(struct student *head); //打印链表

struct student

{

int num;

float score;

struct student *next;

};

int n; //全局变量,用来记录存放了多少数据。

main()

{

struct student *stu, *p;

int n;

stu = creat();

p = stu;

print( p );

printf("Please enter the num to delete: ");

scanf("%d", &n);

print( del(p, n) );

printf("");

system("pause");

}

struct student *creat()

{

struct student *head;

struct student *p1, *p2;

p1 = p2 = (struct student *)malloc(LEN); // LEN是student结构的大小

printf("Please enter the num :");

scanf("%d", &p1->num);

printf("Please enter the score :");

scanf("%f", &p1->score);

head = NULL;

n = 0;

while( p1->num )

{

n++;

if( 1 == n )

{

head = p1;

}

else

{

p2->next = p1;

}

p2 = p1;

p1 = (struct student *)malloc(LEN);

printf("Please enter the num :");

scanf("%d", &p1->num);

printf("Please enter the score :");

scanf("%f", &p1->score);

}

p2->next = NULL;

return head;

}

void print(struct student *head)

{

struct student *p;

printf("There are %d records!", n);

p = head;

if( head )

{

do

{

printf("学号为 %d 的成绩是: %f", p->num, p->score);

p = p->next;

}while( p );

}

}

struct student *del( struct student *head, int num)

{

struct student *p1, *p2;

if( NULL == head )

{

printf("This list is null!");

goto end;

}

p1 = head;

while( p1->num != num && p1->next != NULL)

{

p2 = p1;

p1 = p1->next;

}

if( num == p1->num )

{

if( p1 == head )

{

head = p1->next;

}

else

{

p2->next = p1->next;

}

printf("Delete No: %d succeed!", num);

n = n-1;

}

else

{

printf("%d not been found!", num);

}

end:

return head;

}

三、对链表的插入操作

对链表的插入是指将一个结点插入到一个已有的链表中。为了能做到正确插入,必须解决两个问题:

① 怎样找到插入的位置;

② 怎样实现插入。

我们可以先用指针变量p0指向待插入的结点,p1指向第一个结点。将p0->num与p1->num相比较,如果p0->num>p1-> num ,此时将p1后移,并使p2指向刚才p1所指的结点。

48342be59b32828e0790aa3c7b56ea87.png
80d9406460d005a14f1b1687d1846764.png

案例:

#include

#include

#include

#define LEN sizeof(struct student) // student结构的大小

struct student *creat(); //创建链表

struct student *del(struct student *head, int num); //del函数用于删除结点, *head即链表

//的头指针, num是要删除的结点num。

struct student *insert(struct student *head, struct student *stu_2); // 第一个参数需要被插入的链表

// 第二个参数待插入的结构的地址

void print(struct student *head); //打印链表

struct student

{

int num;

float score;

struct student *next;

};

int n; //全局变量,用来记录存放了多少数据。

void main()

{

struct student *stu, *p, stu_2;

int n;

stu = creat();

p = stu;

print( p );

printf("Please input the num to delete: ");

scanf("%d", &n);

print( del(p, n) );

printf("Please input the num to insert: ");

scanf("%d", &stu_2.num);

printf("Please input the score: ");

scanf("%f", &stu_2.score);

p = insert(stu, &stu_2);

print( p );

printf("");

system("pause");

}

struct student *creat()

{

struct student *head;

struct student *p1, *p2;

p1 = p2 = (struct student *)malloc(LEN); // LEN是student结构的大小

printf("Please enter the num :");

scanf("%d", &p1->num);

printf("Please enter the score :");

scanf("%f", &p1->score);

head = NULL;

n = 0;

while( p1->num )

{

n++;

if( 1 == n )

{

head = p1;

}

else

{

p2->next = p1;

}

p2 = p1;

p1 = (struct student *)malloc(LEN);

printf("Please enter the num :");

scanf("%d", &p1->num);

printf("Please enter the score :");

scanf("%f", &p1->score);

}

p2->next = NULL;

return head;

}

void print(struct student *head)

{

struct student *p;

printf("There are %d records!", n);

p = head;

if( head )

{

do

{

printf("学号为 %d 的成绩是: %f", p->num, p->score);

p = p->next;

}while( p );

}

}

struct student *del( struct student *head, int num)

{

struct student *p1, *p2;

if( NULL == head )

{

printf("This list is null!");

goto end;

}

p1 = head;

while( p1->num != num && p1->next != NULL)

{

p2 = p1;

p1 = p1->next;

}

if( num == p1->num )

{

if( p1 == head )

{

head = p1->next;

}

else

{

p2->next = p1->next;

}

printf("Delete No: %d succeed!", num);

n = n-1;

}

else

{

printf("%d not been found!", num);

}

end:

return head;

}

struct student *insert(struct student *head, struct student *stu_2)

{

struct student *p0, *p1, *p2;

p1 = head;

p0 = stu_2;

if( NULL == head )

{

head = p0;

p0->next = NULL;

}

else

{

while( (p0->num > p1->num) && (p1->next != NULL) ) //两种情况推出while,一:

{

p2 = p1;

p1 = p1->next;

}

if( p0->num <= p1->num )

{

if( head == p1 ) // p1是头结点,插入头部

{

head = p0;

}

else // 普通情况,插入中间

{

p2->next = p0;

}

p0->next = p1;

}

else // p0的num最大,插入到末尾

{

p1->next = p0;

p0->next = NULL;

}

}

n = n+1; // 由于插入了,所以增加了一位数据成员进入链表中。

return head;

}


感谢您的阅读,希望有所收获!会持续更新!下一节共用体!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值