#include <stdio.h>/系统函数。
#include <malloc.h>因为要使用malloc函数。
struct Node /*定义链表结点的类型*/
{//全局变量
int data; /*数据域*/
struct Node* next; /*指针域*/
};
typedef struct Node Node; /*typedef定义类型的别名为Node,方便使用*/
Node* Create(); //返回值是Node类型的函数 /* 创建一个新的链表 */
void Print(Node* head); //传入指针 /* 打印链表 */
void Release(Node* head); /* 释放链表所占的内存空间 */
int main()//主函数。
{
Node* head; /* 前提是struct是全局变量。定义头指针head *///
head = Create(); /* 创建一个新的链表,返回的头指针赋值给head */
Print(head); //只用/* 链表的遍历输出每个元素的值 */
Release(head); /*释放链表每个结点的存储空间*/
return 0;
}
/* 函数功能: 创建一个单链表
函数入口参数:无
函数返回值: 链表的头指针
*/
Node* Create()
{
Node* head, * tail, * p; //头,尾,运动指针// /* head、tail分别指向链表的头结点和尾结点 */
int num;//给输入空间
head = tail = NULL; /* 链表初始化: 空链表 */
printf("请输入一批数据,以-9999结尾: \n");//如果不按要求就会失败。
scanf_s("%d", &num);
while (num != -9999) /* 用户数据输入未结束 */
{
p = (Node*)malloc(sizeof(Node)); /* 申请一块节点的内存用于存放数据 */
p->data = num; /* 将数据存于新结点的data成员中 */
p->next = NULL; /* 新结点的指针域及时赋为空值,当前用不到,要及时存放,不然就成野指针 */
//分情况讨论 挺标准化的。
if (NULL == head) /* 如果原来链表为空 */
{
head = p; /* 则将p赋值给head,p是刚申请的第一个结点 *///p就像TRNA一样,合成蛋白质。
}
else /* 如果原来链表非空 *///尾插法
{
tail->next = p; /* 则将新结点链入尾部成为新的最后一个结点 */
}
tail = p; //一定要经过的步骤 /* 更新tail指针,让其指向新的尾结点处 */
scanf_s("%d", &num); /* 继续读入数据 */
}
return head; /* 返回链表的头指针 */
}
/* 函数功能: 遍历单链表输出每个结点中的元素值
函数入口参数:链表的头指针
函数返回值: 无
*/
void Print(Node* head)
{
Node* p; //上一个函数的p是局部变量 /* 定义工作指针p */
p = head; /* p从头指针开始 */
if (NULL == head) /* 如果链表为空输出提示信息 */
{
printf("链表为空!\n");
}
else
{
printf("链表如下\n");//经典步骤
while (p != NULL) /*用 p来控制循环,p为空指针时停止*/
{
printf("%d ", p->data); /*输出 p当前指向的结点的元素值*/
p = p->next; /* p指向链表的下一个结点处*/
}
}
printf("\n");
}
/* 函数功能: 释放单链表中所有的动态结点
函数入口参数:链表的头指针
函数返回值: 无
*/
void Release(Node* head) /* 仍然是使用遍历的方法扫描每一个结点*/
{
Node* p1, * p2; /* p1用来控制循环,p2指向当前删除结点处*/
p1 = head;
while (p1 != NULL)
{
p2 = p1; /*p2指向当前删除结点处*/
p1 = p1->next; /* p1指向链表下一个结点位置处*/
free(p2); /* 然后通过p2释放动态空间*/
}
printf("链表释放内存成功!\n");
}
尾插法———链表,初学者详解版
最新推荐文章于 2023-02-20 19:53:42 发布