最近一直在忙着写C语言的实验实验10。
一开始就是直接百度希望找到类似的例子进行学习和改进。当然也遇到了一些问题。
作为数据结构的重要内容,先来看看链表的知识吧。以前没接触过链表,学到时,对链表的理解也是一团雾水。
最后自己理了一下。
这里先说一下,链表有动态和静态之分,静态链表太简单了,就不深入讨论了,不过先来一个静态链表的例子,我觉得有助于对动态链表的理解,同时,我也凑一下字数。
一个静态链表的例子(实在看不懂,可以先看下面的链表的介绍)
/*
一个静态链表的例子
*/
#include<stdio.h>
struct Student
{
long num;//学号
double score;//成绩
struct Student *next;//指向下一个学生
};
int main()
{
struct Student a, b, c, *head;
//给结构体中的数据赋值
a.num = 10001;
a.score = 97;
b.num = 10002;
b.score = 85;
c.num = 10003;
c.score = 99;
/*这里相当于把abcd连成一条链子,所以叫链表*/
head = &a;//头指针指向a的地址
a.next = &b;//a的下一个空间指向b的地址
b.next = &c;//b的下一个空间指向c的地址
c.next = NULL;//最后附上空指针
//打印链表结构
do {
printf("%d %5.2f\n", head->num, head->score);
head = head->next;//打印完一个数据后使head指向下一个空间
} while (head!=NULL);
return 0;
}
运行结果:
1.1链表的组成
链表有两个属性,一个是数据属性(域),另一个是指针属性(域)
这个说法可能很拗口,下面我们看一个例子,通过例子来理解。
struct node
{
int date; //数据域,用于储存数据
struct node *next; //指针域,存放地址,找到下一个数据所在的位置
};
图解如下:(图片来源于百度图片)
1.2关于动态链表用到的几个函数及其作用
先说一下什么是动态链表吧
1.2.1什么是动态链表
所谓建立动态链表是指在程序执行过程中从无到有的建立起一个链表,即一个一个的开辟节点和输入各节点的数据,并建立起前后相连的关系。
使用动态链表存储数据,不需要预先申请内存空间,而是在需要的时候才向内存申请。也就是说,动态链表存储数据元素的个数是不限的,想存多少就存多少。
同时,使用动态链表的整个过程,只需操控一条存储数据的链表。当表中添加或删除数据元素时,需要通过 malloc 或 free 函数来申请或释放空间。
1.2.2静态链表和动态链表的区别
或许每个人最终都会有自己的理解,我也是看别人的理解的,这里就不写了,
去看看这篇文章https://blog.csdn.net/zhengqijun_/article/details/78192888
1.2.3使用动态链表过程中用到的两个函数
1:动态申请内存 malloc 函数 (memory allocation)
其原型是:
extern void *malloc(unsigned int num_bytes);
说明:
1)void *
是未确定类型的指针,要用户指定类型,如char *, int *,double *
若没有指定则会报错.
2)如果申请成功,则返回被指向的内存的指针,否则返回 NULL
2.动态内存释放free()函数
其原型是:
void free(void *P)
说明:
与malloc 函数的功能相反,free()函数用来释放由malloc给指针变量申请内存空间。
1.3动态链表的建立
个人觉得应该分成三个步骤
1)定义结构体类型-----构建链表
2)用malloc函数给节点开辟空间
3)给刚才2)步骤开辟的节点传入数据
4)继续开辟空间
5)继续给4)步骤开辟的节点传入数据
6)之后就是开辟空间和传入数据的重复操作
7)数据传入完毕后,释放空间,返回头指针
说的在再清楚,不如看个例子吧。----建立一个动态链表的例子
#include<stdio.h>
#include<stdlib.h>
struct student{
long int num;//学号
float score;//成绩
struct student*next;//指向下一个学生
};
int n=0;//有n个学生数据
/*创建链表函数*/
struct student* creat()
{
struct student *p1,*p2,*head;
p2=p1=(struct student*)malloc(sizeof(struct student));//创建一个动态存储空间,p1,p2同时指向第一个结点
printf("please enter the first student:\n");
scanf("%ld,%f",&p1->num,&p1->score);
head=NULL;//头指针置空
while(p1->num!=0)//以学生学号为例,学号为0时结束循环
{
n=n+1;
if(n==1)head=p1;//头指针指向第一个数据
else p2->next=p1;//否则令表尾指针指向它,及链接到表尾
p2=p1;//p2指向新表尾
p1=(struct student*)malloc(sizeof(struct student));//继续开辟动态存储区
scanf("%ld,%f",&p1->num,&p1->score);//继续输入新结点数据
}
p2->next=NULL;//最终表尾结点的指针域置空
return head;//返回头指针
}
/*输出函数*/
void print(struct student *head)
{
struct student *p1;
p1=head;
while(p1->num!=0)
{
printf("\nnum:%ld,score:%f",p1->num,p1->score);
p1=p1->next;
}
}
void main()
{
struct student *head;
head=creat();//调用函数使得head指向空间首地址
printf("plese printf the num and score\n");
print(head);
}
做实验10遇到的问题
1.1关于链表数据排序问题。
链表和数组有很大区别但是,排序算法都是一样的。如果看懂了我之前写的文章,浅谈排序算法
就不难理解了。
参考链接https://blog.csdn.net/vectory0213/article/details/79168475?tdsourcetag=s_pcqq_aiomsg
个人体会: