数据结构---概念、数据与数据之间的关系(逻辑结构、物理结构)、基本功能、数据结构内容、单向链表(概念、对象、应用)

数据结构

        在数据结构部分,研究数据在内存中如何存储。

        数据存储的形式有两种:变量和数组(数据结构的顺序表)。

一、什么是数据结构?

        数据类型被用来组织和存储数据。

        程序设计 = 数据结构 + 算法

二、数据与数据之间的关系

1、逻辑结构

        数据元素与元素之间的关系。

     1)集合:元素与元素之间平等的集合关系。

     2)线性结构:元素与元素之间存在一对一的关系(eg. 顺序表、链表、队列、栈)。

     3)树形结构:元素与元素之间存在一对多的关系(eg. 二叉树)。

     4)图形结构(网状结构):元素与元素之间存在多对多的关系。

        内存为线形存储结构。

2、物理结构

        数据元素在计算机内存中的存储方式。

        1)顺序结构:在内存中选用一段连续的内存空间进行存储。

                特点:(1) 数据访问方便 (算法复杂度O(1) )。

                           (2) 插入和删除数据时需要移动大量数据。

                           (3) 需要域内存分配 (连续的) 。

                           (4) 可能造成大量内存碎片 (分为内内存碎片和外内存碎片两种 )。

内存碎片分类内存碎片特点
内内存碎片操作系统已分配给程序的内存中部分小内存空间不能再被使用,例如结构体数据类型存储时的中间空闲块
外内存碎片内存中存在大量不连续的空闲块,因分散在内存的不同位置而不能合并成一块连续的大空间,导致程序无法被加载到内存中

        2)链式结构:可以在内存中选用一段不连续的内存空间进行存储。

                给内存元素后加上指针,指针指向元素访问下一个元素。

                特点:(1) 数据访问必须从头遍历 (算法复杂度O(n) );

                           (2) 插入和删除元素方便;

                           (3) 不需要与内存分配 (离散的),是一种动态内存操作 (只要有部分内存空间能放下部分数据,直至存放完全部数据就行)。

        3)索引结构:将要存储的数据的关键字和存储位置之间构建一个索引表。

        4)散列结构(哈希结构):将数据的存储位置与数据元素之间的关键字建立起对应的关系( 哈希函数 )。

        索引结构与散列结构都用于快速定位数据。

三、基本功能

        指针、结构体、动态内存分配。

四、数据结构内容

       数据结构内容包含:顺序表、链式表(单向链表、双向链表、循环链表、内核链表)、栈、队列、二叉树、哈希表、常用算法。

五、单向链表

1、概念

        单向链表是一种常见的线形数据结构,由多个节点组成,每个节点包含两部分:

        1) 数据域:存储结点本身的信息(如数值、字符等)。

        2) 指针域:存储下一个结点的地址,用于指向链表中的下一个结点。

示意图如下:

        特点:整个链表的访问需从第一个结点开始,依次通过指针域找到下一个节点,最后一个结点的指针域为空指针(NULL),单向链表无法访问前一个结点。

2、链表的对象

        链表的对象是存储数据的对象。

        链表对象的属性特征(变量):第一个结点、结点的个数。

        链表对象的行为(函数):创建链表对象、插入数据、删除数据、修改数据、查找数据、销毁链表。

3、单项链表的应用

     1)单向链表的封装

        (1) 封装结点(存放在声明文件中)

/*链表的结点类型*/
typedef struct node
{Data_type_t data;struct node *pnext;
}Node_t;

        (2) 封装对象(存放在声明文件中)

/*链表对象类型*/
typedef struct link
{Node_t *phead;int clen;
}Link_t;

        (3) 创建单向链表函数封装

/*创建单向链表*/
Link_t *create_link()
{Link_t *plink = malloc(sizeof(Link_t));if(NULL == plink){printf("malloc error!\n");return NULL;}plink->phead = NULL;plink->clen = 0;return plink;
}

        (4) 单向链表---头部插入数据函数的封装

/*向单向链表的头部插入数据*/
int insert_link_head(Link_t *plink, Data_type_t data)
{//申请结点Node_t *pnode = malloc(sizeof(Node_t));if(NULL == pnode){printf("malloc error!");return -1;}//初始化结点pnode->data = data;pnode->pnext = NULL;//头插2步插入结点pnode->pnext = plink->phead;plink->phead = pnode;plink->clen++;return 0;
}

        (5) 单向链表---遍历函数的封装

//遍历
void link_for_each(Link_t *plink)
{Node_t *ptmp = plink->phead;while(ptmp != NULL){printf("%d ", ptmp->data);ptmp = ptmp->pnext;}printf("\n");
}

        (6) 单向链表---查找函数的封装

//查找
Node_t *find_link(Link_t *plink, Data_type_t mydata)
{Node_t *ptmp = plink->phead;while(ptmp != NULL){if(mydata == ptmp->data){return ptmp;}ptmp = ptmp->pnext;}return NULL;
}

        (7) 单向链表---遍历函数的封装

//修改
int change_link(Link_t *plink, Data_type_t olddata, Data_type_t newdata)
{Node_t *ptmp = find_link(plink, olddata);if(ptmp != NULL){ptmp->data = newdata;return 0;}return -1;
}

        (8)单向链表---头删函数的封装(删除前需判断是不是空结点)

/*是不是空结点*/
int is_empty_link(Link_t *plink)
{return NULL == plink->phead;
}//删除
int delete_link_head(Link_t *plink)
{if(is_empty_link(plink)){return -1;}Node_t *ptmp;ptmp = plink->phead;plink->phead = ptmp->pnext;free(ptmp);plink->clen--;return 0;
}

        (9) 单向链表---尾部插入数据的函数的封装

/*向单向链表的尾部插入数据*/
int insert_link_tail(Link_t *plink, Data_type_t data)
{//申请结点Node_t *pnode = malloc(sizeof(Node_t));if(NULL == pnode){printf("malloc error!");return -1;}pnode->data = data;pnode->pnext = NULL;if(is_empty_link(plink) == 0){plink->phead = pnode;pnode->pnext = NULL;plink->clen++;}else{Node_t *ptmp = plink->phead;while(ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = pnode;plink->clen++;}return 0;
}

        (10) 单向链表---尾删函数的封装

//尾删
int delete_link_tail(Link_t *plink)
{if(is_empty_link(plink) == 0){return -1;}Node_t *ptmp = plink->phead;if(NULL == ptmp->pnext){delete_link_head(plink);}else{while(ptmp->pnext->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = NULL;plink->clen--;//free(ptmp->pnext);}return 0;
}

        (11) 单向链表---链表销毁函数的封装

//销毁
void destroy_link(Link_t *plink)
{while(is_empty_link(plink) != 0){delete_link_head(plink);}free(plink);printf("success!\n");
}

        (11) 上述代码在封装函数框需包含以下三种头文件,其中“link.h”是自己命名的声明文件,在后续内容中说明

#include<stdio.h>
#include<stdlib.h>
#include"link.h"
     2)单向链表的函数声明
#ifndef _LINK_H
#define _LINK_H/*链表存储的数据的数据类型*/
typedef int Data_type_t;extern Link_t *create_link();
extern int insert_link_head(Link_t *plink, Data_type_t data);
extern void link_for_each(Link_t *plink);
extern Node_t *find_link(Link_t *plink, Data_type_t mydata);
extern int change_link(Link_t *plink, Data_type_t olddata, Data_type_t newdata);
extern int delete_link_head(Link_t *plink);
extern int insert_link_tail(Link_t *plink, Data_type_t data);
extern int delete_link_tail(Link_t *plink);
extern void destroy_link(Link_t *plink);#endif
     3)单向链表的上述函数在主函数中的运行格式
#include<stdio.h>
#include"link.h"int main(int argc, const char *argv[])
{Node_t *ret = NULL;Link_t *plink = create_link();if(NULL == plink){return -1;}insert_link_head(plink, 1);insert_link_head(plink, 2);insert_link_head(plink, 3);insert_link_head(plink, 4);insert_link_head(plink, 5);link_for_each(plink);ret = find_link(plink, 4);if(ret == NULL){printf("not found\n");}else{printf("found %d\n", ret->data);}change_link(plink, 4, 15);link_for_each(plink);delete_link_head(plink); link_for_each(plink);*/尾插、尾删、销毁insert_link_tail(plink, 1);insert_link_tail(plink, 2);insert_link_tail(plink, 3);insert_link_tail(plink, 4);insert_link_tail(plink, 5);link_for_each(plink);delete_link_tail(plink);link_for_each(plink);destroy_link(plink);*/return 0;
}

【END】

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

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

相关文章

CMS框架漏洞

一、WordPress姿势一1.下载vulhub靶场cd /vulhub/wordpress/pwnscriptum docker-compose up -d2.我们进入后台&#xff0c;网址拼接/wp-admin/3.我们进入WP的模板写入一句话木马后门并访问其文件即可GetShell4然后我们拼接以下路径/wp-content/themes/twentyfifteen/404.php&am…

控制建模matlab练习07:比例积分控制-③PI控制器的应用

此练习主要是比例积分控制&#xff0c;包括三部分&#xff1a; ①系统建模&#xff1b; ②PI控制器&#xff1b; ③PI控制器的应用&#xff1b; 以下是&#xff0c;第③部分&#xff1a;PI控制器的应用。 一、比例积分控制的应用模型 1、整个系统是如图&#xff0c;这样一个单位…

【MySQL】MySQL 中的数据排序是怎么实现的?

MySQL 数据排序实现机制详解 MySQL 中的数据排序主要通过 ORDER BY 子句实现&#xff0c;其内部实现涉及多个优化技术和算法选择。让我们深入探讨 MySQL 排序的完整实现机制。 一、排序基础&#xff1a;ORDER BY 子句 基本语法&#xff1a; SELECT columns FROM table [WHERE c…

JVM-垃圾回收器与内存分配策略详解

1.如何判断对象已死1.1 对象引用的4种类型&#xff08;强软弱虚&#xff09;1.1.1 强引用特点&#xff1a;最常见的引用类型&#xff0c;只要强引用存在&#xff0c;对象绝不会被回收Object strongObj new Object(); // 强引用注意&#xff1a;集合类型&#xff0c;如果对象不…

新手向:简易Flask/Django个人博客

从零开始搭建个人博客:Flask与Django双版本指南 本文将详细讲解如何使用两种主流Python框架构建功能完整的个人博客系统。我们将从零开始,分别使用轻量级的Flask框架和功能全面的Django框架实现以下核心功能: 用户认证系统: 用户注册/登录/注销功能 密码加密存储 会话管理…

使用 Trea cn 设计 爬虫程序 so esay

使用 Trea cn 设计 爬虫程序 so esay 在现代数据驱动的时代&#xff0c;网络爬虫已成为数据采集的重要工具。传统的爬虫开发往往需要处理复杂的HTTP请求、HTML解析、URL处理等技术细节。而借助 Trea CN 这样的AI辅助开发工具&#xff0c;我们可以更高效地构建功能完善的爬虫程…

MySQL Redo Log

MySQL Redo Log MySQL主从复制&#xff1a;https://blog.csdn.net/a18792721831/article/details/146117935 MySQL Binlog&#xff1a;https://blog.csdn.net/a18792721831/article/details/146606305 MySQL General Log&#xff1a;https://blog.csdn.net/a18792721831/artic…

项目实战1:Rsync + Sersync 实现文件实时同步

项目实战&#xff1a;Rsync Sersync 实现文件实时同步 客户端中数据发生变化&#xff0c;同步到server端&#xff08;备份服务器&#xff09;。 Rsync&#xff1a;负责数据同步&#xff0c;部署在server端。 Sersync&#xff1a;负责监控数据目录变化&#xff0c;并调用rsync进…

Spring Boot 全 YAML 配置 Liquibase 教程

一、项目初始化配置 1.1 创建 Spring Boot 项目 通过 Spring Initializr 生成基础项目&#xff0c;配置如下&#xff1a; ​​Project​​: Maven​​Language​​: Java​​Spring Boot​​: 3.5.3&#xff08;最新稳定版&#xff09;​​Project Metadata​​: Group: com…

STM32-驱动OLED显示屏使用SPI(软件模拟时序)实现

本章概述思维导图&#xff1a;SPI通信协议SPI通信协议介绍SPI通讯&#xff1a;高速的、串行通讯、全双工、同步、总线协议&#xff1b;&#xff08;通过片选信号选中设备&#xff09;&#xff1b;注&#xff1a;SPI通讯通过片选信号选中设备&#xff0c;串口通讯通过端口号选中…

Easy系列PLC相对运动指令实现定长输送(ST源代码)

汇川Easy系列PLC总线伺服转矩控制功能块 Easy系列PLC总线伺服转矩控制功能块(详细PDO配置+完整ST源代码)_pdo中添加目标力矩然后映射到轴中-CSDN博客文章浏览阅读215次。Easy系列PLC如何实现轮廓速度模式PV速度模式Easy系列PLC如何实现轮廓速度模式PV速度控制_汇川easy plc轮廓…

SpringCloud学习第一季-4

目录 16.SpringCloud Alibaba Nacos服务注册和配置中心 SpringCloud Alibaba简介 1. 为什么出现 SpringCloud Alibaba 2. SpringCloud Alibaba带来了什么 2.1 能干什么 2.2 去哪里下载 2.3 怎么玩 3. 学习资料的获取 17.SpringCloud Alibaba Nacos服务注册和配置中心 …

嵌入式开发学习———Linux环境下数据结构学习(五)

折半查找&#xff08;二分查找&#xff09;适用于已排序的数组&#xff0c;通过不断缩小查找范围定位目标值。int binarySearch(int arr[], int size, int target) {int left 0, right size - 1;while (left < right) {int mid left (right - left) / 2;if (arr[mid] t…

(一)React +Ts(vite创建项目/useState/Props/Interface)

文章目录 项目地址 一、React基础 1.1 vite创建 1. 创建项目 2. 安装项目所需环境 1.2 jsx 1. 三元表达式 1.3 基础 1. 创建第一个组件 2. 安装boostrap 3. 插件常用命令 4. map 二、组件 2.1 useState 1. useState 2. 使用 3.更新对象 4. 更新数组(增,删,改) 5. 使用immer…

网关和BFF是如何演化的

BFF&#xff08;Backend For Frontend&#xff09;:对返回的数据结构进行聚合、裁剪、透传等适配逻辑。 适用于API网关之后的数据聚合、裁剪与透传简化客户端逻辑&#xff0c;减少网络开销敏感数据过滤 BFF逻辑层 架构没有最好&#xff0c;要看是否满足当前的业务场景。 业务的…

SQL中的WITH语句(公共表表达式CTE)解释

SQL中的WITH语句&#xff08;公共表表达式CTE&#xff09; WITH语句&#xff0c;也称为公共表表达式&#xff08;Common Table Expression&#xff0c;CTE&#xff09;&#xff0c;是SQL中一种强大的功能&#xff0c;它允许你创建临时结果集&#xff0c;这些结果集可以在后续的…

服务器地域选择指南:深度分析北京/上海/广州节点对网站速度的影响

更多云服务器知识&#xff0c;尽在hostol.com你准备开一个覆盖全国的线上零食店&#xff0c;现在万事俱备&#xff0c;只差一个核心问题没解决&#xff1a;你唯一的那个总仓库&#xff0c;应该建在哪里&#xff1f;是建在哈尔滨&#xff0c;让南方的朋友下单后&#xff0c;一包…

桶排序-Java实现

桶排序是一种分配式排序算法&#xff0c;将元素分到有限数量的桶里&#xff0c;每个桶再单独排序&#xff08;比如用插入排序&#xff09;&#xff0c;最后依次把各个桶中的元素取出来即完成排序。 时间复杂度&#xff1a;最佳 O(n) | 平均 O(n n/k k) | 最差 O(n) 空间复杂…

oracle知识

这里写自定义目录标题Oracle常用的数据类型&#xff1a;Oracle实操&#xff1a;创建数据表Oracle约束建表的时候设置约束&#xff1a;表创建后添加添加约束&#xff1a;Oracle常用的数据类型&#xff1a; Oracle实操&#xff1a;创建数据表 Oracle约束 建表的时候设置约束&…

超级人工智能+无人机操控系统,振兴乡村经济的加速器,(申请专利应用),严禁抄袭!

无人机边缘智能系统&#xff1a;山林珍稀资源探测的完整架构与实战指南本人设计的多模态边缘AI系统已在秦岭山区完成实地验证&#xff0c;对7种高价值食用菌识别准确率达94.3%&#xff0c;定位误差小于0.8米一、前沿技术融合的商业化机遇根据Gartner 2025年技术成熟度曲线分析&…