数据结构:简单记录顺序表、链表、栈、队列

初学者很容易认为顺序表、链表、栈、队列是四种并列的数据结构,其实仔细想想并不是。

注意区分:

顺序表和链表是指数据的存储结构,是线性表的一种,顺序表一般指的就是数组,数据存储的逻辑顺序和物理顺序都是连续的,链表的数据在逻辑上是连续的,但是物理上并不是连续的。

而栈和队列应该算是一种数据的存取逻辑,栈是中先进后出的逻辑,队列是先进先出的逻辑;

栈这种数据存取的逻辑结构可以用顺序表这种数据存储结构来实现,也可以用链表来实现;同样的,队列可以用顺序表来实现,也可以用链表来实现。

一般的,我们的业务需求可能是需要一个栈或者一个队列,比如函数的入栈和出栈,就需要栈这种逻辑结构,比如操作系统中任务的调度,常常就需要用到队列这种逻辑结构;

那么,这两种逻辑结构是怎么来实现的?可以用顺序表或者链表。

由此我们可以看到,这里可以进行组合。

顺序表实现的栈,也就是顺序栈;

链表实现的栈,也就是链栈;

顺序表实现的队列,也就是顺序队列;

链表实现的队列,也就是链队列;

另外,链表还可以分为单链表,支持单向检索,双链表,支持双向检索,单向循环链表,支持到末尾后又回到开头,双向循环链表,支持顺时钟转和逆时钟转;

从另一个方面来考虑,我们可以把顺序表和链表理解成栈和队列的驱动,顺序表和链表,通常都会封装出增删改查等具体操作,然后栈和队列调用这些函数来实现业务中数据的存取逻辑。

等等。

这些具体是怎么回事呢?接下来分别记录一下。

顺序表

类似的内容很多,直接参考这篇吧

【数据结构】——顺序表介绍(独家介绍,小白必看!!)-CSDN博客

补充说明

✔.

理解顺序表结构体

一开始我的理解是,这里数据类型已经确定了,容量和大小不是应该给一个就可以了吗?

容量就=size*sizeof(int)

我以为size和capacity都是对数组的描述。

其实,这里不是这么理解的。

array是数组的首地址指针,也就是顺序表的句柄;

size指的是顺序表的有效长度,而不是数组的长度,千万注意;

capacity指的是数组的长度;

意思就是,我们建了个数组来实现顺序表,其中,数组的长度就是我后面顺序表能容纳元素的容量capacity,而size就是当前顺序表的长度,比如我往顺序表放一个数据,size就是1,放两个数据,size就是2……以此类推。

✔.

动态顺序表

因为数组在创建后大小就会固定下来,所以如果我们直接使用数组来实现顺序表,那么就不够灵活,无法实现扩容。

所以我们这里使用动态创建内容的方式。

在扩容时用realloc,当realloc的第一个参数为0时,其效果等同于malloc,用realloc可以完美实现最初开辟空间和增容的功能。

C 标准库 – <stdlib.h> | 菜鸟教程

✔.

顺序表常见操作

头插、尾插,头删、尾删、遍历、特定位置插入、查找特定元素的位置、求顺序表长度、删除特定位置的元素、排序、清空、销毁等等。

头插就是插入时将新元素插在表头部,尾插就是插入时将新元素插在表尾部。

同理,头删就是删除头部,尾删就是删除尾部。

✔.

顺序表首地址就表示该顺序表。

✔.

有些场景需要移动元素

比如头插,就需要将所有数据相应往后移动一个地址空间,头删,就需要将所有数据相应往前移动一个地址空间,再比如在指定位置插入,就需要将包括插入位置在内的所有之后的元素数据往后移动……总之就是,顺序表是从首地址开始的,并且每个位置都会有值。

而且,首地址是固定的,代表着顺序表本身。

链表不用整体移动数据是因为其存储时并不是连续的。

✔.

特定位置插入时,有多种情况,其中,头插和尾插可以直接调用头插和尾插函数。

就是说,能复用的函数就尽量复用。

链表

类似的内容很多,直接参考这两篇吧

单链表

【数据结构】——单链表超详细介绍(独家介绍,小白必看!!!)-CSDN博客

双链表

数据结构——双向链表-CSDN博客

补充说明

✔.

链表需要有一个元素来保存头指针,要不然链表就丢失了。我们需要用一个变量来存储指向首个有效结点的指针。这样的话是不算头结点的。

✔.

另外,有一种带头结点的链表。可以使得某些情况下的算法变得简洁高效,其实是因为可以让循环创建更加统一规整。

此时,头插法不是插在链表最前面,因为头结点永远在最前面,而是插入的位置是在头结点之后,第一个有效结点之前。

✔.

为了更好地管理链表,可以保存首尾结点的指针以及元素长度

如果没有这种管理,有些情况会较为复杂,比如尾插法时,如果没有预先保存尾部元素的指针,那么就需要从给定的头指针开始往后遍历判断,直到遍历到最后一个元素时才能执行插入操作。

这种情况下,直接传入List结构体变量指针来表示当前链表。

✔.任意位置插入

尾部插入时,有尾指针来管理。

那么任意位置插入呢?

任意位置按值插入时,需要先让链表是有序的,然后才能按值插入。

✔.

链表因为无法随机存取,所以有些时候需要遍历链表才能完成相应功能。

单链表向前操作比较麻烦,向后操作比较简单。

比如删除某个结点时,需要将目标结点的上一个结点的next重新赋值成目标结点的下一个结点,我们遍历查找到目标结点,可以根据结构体找到下一个结点,但是不能反向怎么找到上一个结点呢?

重新再遍历一遍?

我们换个思路

比如我们要删除这第二个结点

但是有个问题就是第二个结点的上一个结点不好找,除非重新遍历一遍。

现在我们不想遍历。

这样来操作,我们把第二个结点的下一个结点的数据复制到当前结点,然后就可以将这个问题转换成删除当前结点的下一个结点,即从删除第二个结点的问题,转变成了删除第三个结点的问题。

也就是说,将向前的问题转换成了向后的问题。

✔.

双链表

单链表头插头删效率十分的高,但是要在中间或者尾部进行插入删除操作时,需要找到前驱节点,而且单链表难以逆序,这导致单链表具有一定的局限性。

为了克服这单向性的缺点,我们的前辈们设计出了双向链表

✔.

链表在删除结点后,需要free释放结点空间。

因为链表结点是一个一个地malloc出来的,所以要一个一个地释放。

顺序表是一次创建出来的,所以直接释放申请出来的指针即可。

也就是说,free和malloc是一一对应的。

✔.

销毁操作不应该由用户来进行。

 

栈是限定仅在表尾进行插入和删除操作的线性表。

类似的内容很多,直接参考这篇吧

数据结构之——栈_数据结构栈_WenJieya的博客-CSDN博客

补充说明

✔.

栈的结构体

栈底地址,也就是该栈的地址;

栈容量;

栈顶地址,也可以用来表示当前栈大小;

✔.

栈顶的起始地址索引

栈顶索引top从0开始还是从-1开始,都可以,二者的区别是,如果从0开始,存数据时,需要先存数据,然后top指针+1,如果是从-1开始,则索引需要先+1再存数据,取数据时的过程正好相反。其他没啥区别。top指向的是下一个能存放数据的地址空间,等待数据来存。

✔.

两个辅助函数

判断栈满和判断栈空

✔.

栈动态扩容

✔.

栈的操作通常只有入栈和出栈,然后就是显示。

队列

类似的内容很多,直接参考这篇吧

【数据结构之队列系列】队列详解_结构体队列-CSDN博客

补充说明

✔.

栈和队列都是个受限的线性表。

链队列结构体如下:

✔.

队头指针等于队尾指针时,队列为空。

✔.

顺序队列

✔.

循环队列

针对以下这种情况

队尾已经到了容量最大指针处,但是队列头之前因为有些数据被取出所以还有空间可以使用,此时,如果再在队尾插入数据,其实已经越界了,为了更好地利用队列头空间,就可以设计一种循环队列。

相关视频可参考:

C语言代码实现严蔚敏数据结构

更多补充

几种常见的排序算法

冒泡排序

直接排序

快速排序

……

经典的十种排序算法 C语言版_c语言排序_Johnny-He的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/146963.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nodejs+vue交通违章查询及缴费elementui

第三章 系统分析 10 3.1需求分析 10 3.2可行性分析 10 3.2.1技术可行性&#xff1a;技术背景 10 3.2.2经济可行性 11 3.2.3操作可行性&#xff1a; 11 3.3性能分析 11 3.4系统操作流程 12 3.4.1管理员登录流程 12 3.4.2信息添加流程 12 3.4.3信息删除流程 13 第四章 系统设计与…

Django模板加载与响应

前言 Django 的模板系统将 Python 代码与 HTML 代码解耦&#xff0c;动态地生成 HTML 页面。Django 项目可以配置一个或多个模板引擎&#xff0c;但是通常使用 Django 的模板系统时&#xff0c;应该首先考虑其内置的后端 DTL&#xff08;Django Template Language&#xff0c;D…

Git使用【下】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;标签管理理解标签标签运用 …

Grander因果检验(格兰杰)原理+操作+解释

笔记来源&#xff1a; 1.【传送门】 2.【传送门】 前沿原理介绍 Grander因果检验是一种分析时间序列数据因果关系的方法。 基本思想在于&#xff0c;在控制Y的滞后项 (过去值) 的情况下&#xff0c;如果X的滞后项仍然有助于解释Y的当期值的变动&#xff0c;则认为 X对 Y产生…

插入排序与希尔排序

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言&#xff1a; 这两个排序在思路上有些相似&#xff0c;所以有人觉得插入排序和希尔排序差别不大&#xff0c;事实上&#xff0c;他们之间的差别不小&#xff0c;插入排序只是希尔排序的最后一步。 目录 前言&#xff1a;…

华为数通方向HCIP-DataCom H12-831题库(单选题:161-180)

第161题 某台路由器Router LSA如图所示,下列说法中错误的是? A、本路由器已建立邻接关系 B、本路由器为DR C、本路由支持外部路由引入 D、本路由器的Router ID为10.0.12.1 答案: B 解析: 一类LSA的在transnet网络中link id值为DR的route id ,但Link id的地址不是10.0.12.…

对pyside6中的textedit进行自定义,实现按回车可以触发事件。

以下方法不算最优解。因为这个ui文件很容易重新编译&#xff0c;使写在ui.py里面的代码被删掉。 所以更好的方法应该是在主代码当中单独定义控件。并且使用布局添加控件到界面中。 以下内容纯为旧版实现&#xff0c;仅供参考&#xff1a; 我的实现方法是&#xff0c;先用qt de…

学信息系统项目管理师第4版系列15_资源管理基础

1. 项目资源 1.1. 实物资源 1.1.1. 着眼于以有效和高效的方式&#xff0c;分配和使用完成项目所需的实物资源 1.1.2. 包括设备、材料、设施和基础设施 1.2. 团队资源 1.2.1. 人力资源 1.2.2. 包含了技能和能力要求 2. 人力资源管理 2.1. 不仅是组织中最重要的资源之一&…

设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)

目录 概述概念适用场景结构类图 衍化过程业务需求基本的数据访问程序工厂方法实现数据访问程序抽象工厂实现数据访问程序简单工厂改进抽象工厂使用反射抽象工厂反射配置文件衍化过程总结 常见问题总结 概述 概念 抽象工厂模式是一种创建型设计模式&#xff0c;它提供了一种将相…

【开发篇】十、Spring缓存:手机验证码的生成与校验

文章目录 1、缓存2、用HashMap模拟自定义缓存3、SpringBoot提供缓存的使用4、手机验证码案例完善 1、缓存 缓存是一种介于数据永久存储介质与数据应用之间的数据临时存储介质使用缓存可以有效的减少低速数据读取过程的次数&#xff08;例如磁盘IO&#xff09;&#xff0c;提高…

Shapiro-Francia正态检验

Shapiro-Francia检验是一种用于检验数据是否来自正态分布的统计方法。它是Shapiro-Wilk检验的一个变种&#xff0c;通常适用于小到中等样本大小的数据集。Shapiro-Francia检验的核心思想是通过计算统计量来评估数据的正态性。 Shapiro-Francia检验的零假设是数据来自正态分布&…

26 docker前后端部署

[参考博客]((257条消息) DockerNginx部署前后端分离项目(SpringBootVue)的详细教程_在docker中安装nginx实现前后端分离_这里是杨杨吖的博客-CSDN博客) (DockerNginx部署前后端分离项目(SpringBootVue)) 安装docker # 1、yum 包更新到最新 yum update # 2、安装需要的软件包…

JavaSE | 初识Java(七) | 数组 (下)

Java 中提供了 java.util.Arrays 包 , 其中包含了一些操作数组的常用方法 代码实例&#xff1a; import java.util.Arrays int[] arr {1,2,3,4,5,6}; String newArr Arrays.toString(arr); System.out.println(newArr); // 执行结果 [1, 2, 3, 4, 5, 6] 数组拷贝 代码实例…

cf 解题报告 01

E. Power of Points Problem - 1857E - Codeforces 题意&#xff1a; 给你 n n n 个点&#xff0c;其整数坐标为 x 1 , … x n x_1,\dots x_n x1​,…xn​&#xff0c;它们位于一条数线上。 对于某个整数 s s s&#xff0c;我们构建线段[ s , x 1 s,x_1 s,x1​], [ s , x…

C语言结构体指针学习

结构体变量存放内存中&#xff0c;也有起始地址&#xff0c;定义一个变量来存放这个地址&#xff0c;那这个变量就是结构体指针&#xff1b; typedef struct mydata{int a1;int a2;int a3; }mydata;void CJgtzzView::OnDraw(CDC* pDC) {CJgtzzDoc* pDoc GetDocument();ASSERT…

npm ,yarn 更换使用国内镜像源,淘宝源

背景 文章首发地址 在平时开发当中&#xff0c;我们经常会使用 Npm&#xff0c;yarn 来构建 web 项目。但是npm默认的源的服务器是在国外的&#xff0c;如果没有梯子的话。下载速度会特别慢。那有没有方法解决呢&#xff1f; 其实是有的&#xff0c;设置国内镜像即可&#x…

基于web的医院预约挂号系统/医院管理系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…

如何解决版本不兼容Jar包冲突问题

如何解决版本不兼容Jar包冲突问题 引言 “老婆”和“妈妈”同时掉进水里&#xff0c;先救谁&#xff1f; 常言道&#xff1a;编码五分钟&#xff0c;解冲突两小时。作为Java开发来说&#xff0c;第一眼见到ClassNotFoundException、 NoSuchMethodException这些异常来说&…

八大排序(三)堆排序,计数排序,归并排序

一、堆排序 什么是堆排序&#xff1a;堆排序&#xff08;Heap Sort&#xff09;就是对直接选择排序的一种改进。此话怎讲呢&#xff1f;直接选择排序在待排序的n个数中进行n-1次比较选出最大或者最小的&#xff0c;但是在选出最大或者最小的数后&#xff0c;并没有对原来的序列…

k8s--storageClass自动创建PV

文章目录 一、storageClass自动创建PV1.1 安装NFS1.2 创建nfs storageClass1.3 测试自动创建pv 一、storageClass自动创建PV 这里使用NFS实现 1.1 安装NFS 安装nfs-server&#xff1a; sh nfs_install.sh /mnt/data03 10.60.41.0/24nfs_install.sh #!/bin/bash### How to i…