没有合适的资源?快使用搜索试试~ 我知道了~
链表概述 链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。 链表的各类操作包括:学习单向链表的创建、删除、 插入(无序、有序)、输出、 排序(选择、插入、冒泡)、反
资源推荐
资源详情
资源评论
C++中链表操作实例分析中链表操作实例分析
链表概述
链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一
个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两
个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元
素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链
表到此结束。
链表的各类操作包括:学习单向链表的创建、删除、 插入(无序、有序)、输出、 排序(选择、插入、冒泡)、反序等
等。
单向链表的图示:
—->[NULL] head
图1:空链表
—->[p1]—->[p2]…—->[pn]—->[NULL] head p1->next p2->next pn->next
图2:有N个节点的链表
创建n个节点的链表的函数为:
#include “stdlib.h”
#include “stdio.h”
#define NULL 0
#define LEN sizeof(struct student)
struct student
{
int num; //学号
float score; //分数,其他信息可以继续在下面增加字段
struct student *next; //指向下一节点的指针
};
int n; //节点总数
/*
==========================
功能:创建n个节点的链表
返回:指向链表表头的指针
==========================
*/
struct student *Create()
{
struct student *head; //头节点
struct student *p1 = NULL; //p1保存创建的新节点的地址
struct student *p2 = NULL; //p2保存原链表最后一个节点的地址
n = 0; //创建前链表的节点总数为0:空链表
p1 = (struct student *) malloc (LEN); //开辟一个新节点
p2 = p1; //如果节点开辟成功,则p2先把它的指针保存下来以备后用
if(p1==NULL) //节点开辟不成功
{
printf (“Cann’t create it, try it again in a moment!”);
return NULL;
}
else //节点开辟成功
{
head = NULL; //开始head指向NULL
printf (“Please input %d node — num,score: “, n + 1);
scanf (“%d %f”, &(p1->num), &(p1->score)); //录入数据
}
while(p1->num != 0) //只要学号不为0,就继续录入下一个节点
{
n += 1; //节点总数增加1个
if(n == 1) //如果节点总数是1,则head指向刚创建的节点p1
{
head = p1;
p2->next = NULL; //此时的p2就是p1,也就是p1->next指向NULL。
}
else
{
p2->next = p1; //指向上次下面刚刚开辟的新节点
}
p2 = p1; //把p1的地址给p2保留,然后p1产生新的节点
p1 = (struct student *) malloc (LEN);
printf (“Please input %d node — num,score: “, n + 1);
scanf (“%d %f”, &(p1->num), &(p1->score));
}
p2->next = NULL; //此句就是根据单向链表的最后一个节点要指向NULL
free(p1); //p1->num为0的时候跳出了while循环,并且释放p1
p1 = NULL; //特别不要忘记把释放的变量清空置为NULL,否则就变成”野指针”,即地址不确定的指针
return head; //返回创建链表的头指针
}
输出链表中节点的函数为:
/*
===========================
功能:输出节点
返回: void
===========================
*/
void Print(struct student *head)
{
struct student *p;
printf (“\nNow , These %d records are:\n”, n);
p = head;
if(head != NULL) //只要不是空链表,就输出链表中所有节点
{
printf(“head is %o\n”, head); //输出头指针指向的地址
do
{
/*
输出相应的值:当前节点地址、各字段值、当前节点的下一节点地址。
这样输出便于读者形象看到一个单向链表在计算机中的存储结构,和我们
设计的图示是一模一样的。
*/
printf (“%o %d %5.1f %o\n”, p, p->num, p->score, p->next);
p = p->next; //移到下一个节点
}
while (p != NULL);
}
}/*
===========================
功能:输出节点
返回: void
===========================
*/
void Print(struct student *head)
{
struct student *p;
printf (“\nNow , These %d records are:\n”, n);
p = head;
if(head != NULL) //只要不是空链表,就输出链表中所有节点
{
printf(“head is %o\n”, head); //输出头指针指向的地址
do
{
/*
输出相应的值:当前节点地址、各字段值、当前节点的下一节点地址。
这样输出便于读者形象看到一个单向链表在计算机中的存储结构,和我们
设计的图示是一模一样的。
*/
printf (“%o %d %5.1f %o\n”, p, p->num, p->score, p->next);
p = p->next; //移到下一个节点
}
while (p != NULL);
}
}
单向链表的删除图示:
—->[NULL] head
图3:空链表
从图3可知,空链表显然不能删除
—->[1]—->[2]…—->[n]—->[NULL](原链表)
head 1->next 2->next n->next
—->[2]…—->[n]—->[NULL](删除后链表)
head 2->next n->next
图4:有N个节点的链表,删除第一个节点
结合原链表和删除后的链表,就很容易写出相应的代码。操作方法如下:
1、你要明白head就是第1个节点,head->next就是第2个节点;
2、删除后head指向第2个节点,就是让head=head->next,OK这样就行了。
—->[1]—->[2]—->[3]…—->[n]—->[NULL](原链表)
head 1->next 2->next 3->next n->next
—->[1]—->[3]…—->[n]—->[NULL](删除后链表)
head 1->next 3->next n->next
图5:有N个节点的链表,删除中间一个(这里图示删除第2个)
结合原链表和删除后的链表,就很容易写出相应的代码。操作方法如下:
1、你要明白head就是第1个节点,1->next就是第2个节点,2->next就是第3个节点;
2、删除后2,1指向第3个节点,就是让1->next=2->next。
删除指定学号的节点的函数为:
/*
==========================
功能:删除指定节点
(此例中是删除指定学号的节点)
返回:指向链表表头的指针
==========================
*/
struct student *Del (struct student *head, int num)
{
struct student *p1; //p1保存当前需要检查的节点的地址
struct student *p2; //p2保存当前检查过的节点的地址
if (head == NULL) //是空链表(结合图3理解)
{
printf (“\nList is null!\n”);
return head;
}
//定位要删除的节点
p1 = head;
while (p1->num != num && p1->next != NULL) //p1指向的节点不是所要查找的,并且它不是最后一个节点,就继续往下
找
{
p2 = p1; //保存当前节点的地址
p1 = p1->next; //后移一个节点
}
if(p1->num==num) //找到了。(结合图4、5理解)
{
if (p1 == head) //如果要删除的节点是第一个节点
{
head = p1->next; //头指针指向第一个节点的后一个节点,也就是第二个节点。这样第一个节点就不在链表中,即删
除
剩余15页未读,继续阅读
资源评论
weixin_38697659
- 粉丝: 1
- 资源: 898
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- bdwptqmxgj11.zip
- onnxruntime-win-x86
- onnxruntime-win-x64-gpu-1.20.1.zip
- vs2019 c++20 语法规范 头文件 <ratio> 的源码阅读与注释,处理分数的存储,加减乘除,以及大小比较等运算
- 首次尝试使用 Win,DirectX C++ 中的形状渲染套件.zip
- 预乘混合模式是一种用途广泛的三合一混合模式 它已经存在很长时间了,但似乎每隔几年就会被重新发现 该项目包括使用预乘 alpha 的描述,示例和工具 .zip
- 项目描述 DirectX 引擎支持版本 9、10、11 库 Microsoft SDK 功能相机视图、照明、加载网格、动画、蒙皮、层次结构界面、动画控制器、网格容器、碰撞系统 .zip
- 项目 wiki 文档中使用的代码教程的源代码库.zip
- 面向对象的通用GUI框架.zip
- 基于Java语言的PlayerBase游戏角色设计源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功