C++数据结构笔记(2)线性表顺序存储的底层实现

news2024/11/19 9:33:08

本章总结单链表的顺序存储方式及其C++实现,重点的理论只需要熟背以下3条:

1.线性表是0个或者多个数据元素的有限序列,其中数据元素类型相同

2.线性表可以逐项访问和顺序存储

3.有顺序存储和链式存储两种存储方式。

接下来,通过动态数组的方式实现顺序存储结构的单链表

首先在目录文件夹中定义一个头文件Dymanic_Array.h,便于代码的复用,具体内容包含:

#ifndef DYNAMIC_ARRAY_H
#define DYNAMIC_ARRAY_H

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

//动态增长内存,将存放的数据的内存放在堆上面。
//动态数组:申请内存 拷贝数据 释放内存 
//容量capacity表示我的这块内存空间中一共可以存放多少元素
//size用于记录当前数组中具体的元素个数

typedef struct Dymanic_Array
{
	int *pAddr; //存放数据的地址 
	int size;
	int capacity;	
}Dymanic_Array; 

//由于返回的各种数据要存放在结构体中,因此要定义位结构体类型的方法
 
Dymanic_Array*Init_Array();
//插入
void Push_Back_Array(Dymanic_Array* arr,int val);
//两个参数的值分别为目标数组,以及插入元素的值
//根据值删除
void RemoveByValue_Array(Dymanic_Array* arr,int val);
//根据位置删除
void RemoveByPos_Array(Dymanic_Array* arr,int pos);
//查找
int Find_Array(Dymanic_Array* arr,int val);
//打印
void Print_Array(Dymanic_Array* arr);
//释放内存 
void FreeSpace_Array(Dymanic_Array* arr);
//清空数组  
void Clear_Array(Dymanic_Array* arr); 
//获得当前容器的容量 
int Capacity_Array(Dymanic_Array* arr);
//获取当前容器中元素的个数 
int Size_Array(Dymanic_Array* arr);
//获取某一位置的元素
int At_Array(Dymanic_Array* arr,int pos);
 


#endif

在此头文件中,主要声明了该数据结构的各种方法,包含:初始化、插入元素、按元素值删除元素、按位置删除元素、查找元素、打印元素、释放内存、清空内容、获取容量、获取元素个数、获取某位置上的元素

然后,在同一目录下创建Dymanic_Array.c文件,用于实现数据结构的具体操作。头部声明头文件:

#include "Dymanic_Array.h"

初始化数据结构

Dymanic_Array*Init_Array(){
	//申请内存
	Dymanic_Array* myArray =(Dymanic_Array*) malloc(sizeof(Dymanic_Array));
	//动态分配内存时一定要记住强转类型的操作! 
	//初始化 
	myArray->size=0;
	myArray->capacity=20;
	//预定义容量为20 
	myArray->pAddr=(int *)malloc(sizeof(int)*myArray->capacity);
	//获取动态数组首地址 
	return myArray;
}

插入元素

void Push_Back_Array(Dymanic_Array* arr,int value){
	if(arr==NULL)
		return;
	//判断空间是否足够
	if(arr->size == arr->capacity)
	{
		//1.将新的空间扩展为原有的2倍 
		int* newSpace =(int*)malloc(sizeof(int)* arr->capacity*2);
		//2.拷贝数据到新的空间
		memcpy(newSpace,arr->pAddr,arr->capacity*sizeof(int));
		//3.释放旧空间的内存
		free(arr->pAddr);
		//更新容量
		arr->capacity= arr->capacity*2;
		arr->pAddr=newSpace;
	} 
	//插入新元素
	arr->pAddr[arr->size] =value; 
	arr->size++;
}

按元素值删除元素

void RemoveByValue_Array(Dymanic_Array* arr,int value){
	if(arr==NULL)
		return;
	//找到值的位置
	int pos=-1;
	 for(int i=0;i<arr->size;i++)
	 {
	 	if(arr->pAddr[i]==value)
	 	{
	 		pos=i;
	 		break;
	 		//因为只删除一个,因此找到后就要退出循环 
	 		//如果想删除多个,只需要将位置存储在数组里面即可~ 
		}
	 		
	 }
	 //再度根据位置删除!
	RemoveByPos_Array(arr,pos); 
}

按位置删除元素

void RemoveByPos_Array(Dymanic_Array* arr,int pos){
	if(arr==NULL)
		return;
	//判断位置是否有效
	if(pos<0||pos>arr->size) 
		return;
	//删除元素:本质思想是元素覆盖!
	for(int i=pos;i<arr->size-1;i++)
	{
		arr->pAddr[i]=arr->pAddr[i+1];
	} 
	//数量减一
	arr->size--; 
}

查找元素

int Find_Array(Dymanic_Array* arr,int value){
	if(arr==NULL)
		return -1;
		//统一未寻找到的返回值 
	//查找 
	int pos=-1;
	 for(int i=0;i<arr->size;i++)
	 {
	 	if(arr->pAddr[i]==value)
	 	{
	 		pos=i;
	 		break;
	 		//同按照位置删除的操作完全一致 
		}	
	 }
	return pos;
}

打印元素

void Print_Array(Dymanic_Array* arr){
	if(arr==NULL)
		return;
	for(int i=0;i< arr->size;i++)
		printf("%d ",arr->pAddr[i]);
	printf("\n"); 
}

释放内存

void FreeSpace_Array(Dymanic_Array* arr){
	if(arr==NULL)
		return;
	//如果传入的是空数组,直接返回空,增加程序的健壮性,其他函数内部的操作亦同理~ 
	if(arr->pAddr!=NULL)
	{
		free(arr->pAddr);
	}
	free(arr);
	
}

清空内容

void Clear_Array(Dymanic_Array* arr){
	if(arr==NULL)
		return;
	arr->size=0;
	//相当于直接跳过初始化pAddr的过程,清空内部的元素 	
}

获取容量

int Capacity_Array(Dymanic_Array* arr){
	if(arr==NULL)
		return -1;
	return arr->capacity;
}

获取元素个数

int Size_Array(Dymanic_Array* arr){
	if(arr==NULL)
		return -1;
	return arr->size;
}

获取某位置上的元素

int At_Array(Dymanic_Array* arr,int pos){
	return arr->pAddr[pos];
}

最后,在同一目录下创建main.cpp/main.c文件来测试该数据结构的功能是否能实现,此次笔者采用c++,如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include"Dymanic_Array.h"

using namespace std;

void test01(){
	Dymanic_Array*myArray=Init_Array();
	//初始化
	for(int i=1;i<=10;i++)
		Push_Back_Array(myArray,i);
	Print_Array(myArray);
	FreeSpace_Array(myArray);
	
} 
 
int main(int argc, char** argv) {
	test01();
	return 0;
}

 综上,该数据结构能满足线性表顺序存储中的常见操作。

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

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

相关文章

Android 逆向入门保姆级教程

作者&#xff1a;37手游移动客户端团队 前言 什么是 Android 逆向开发&#xff1f; Android 逆向开发是指对已发布的 Android 应用进行分析和破解&#xff0c;以了解应用程序的内部工作原理&#xff0c;获取应用程序的敏感信息&#xff0c;或者修改应用程序的行为。逆向开发可…

全网最牛,接口自动化测试mock框架模块实战,入门到高阶...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 mock的介绍 py3已…

基于Docker-compose实现的Postgresql-11的主从复制

参考文章&#xff1a; http://t.csdn.cn/EnOVn http://t.csdn.cn/XTJqZ 记录一次主从复制的配置经历 服务器主从角色分配 ipdb 版本角色192.168.33.23411主192.168.33.22511从 docker-compose.yml文件 version: "3.3" services:postgres:image: postgresql-gis:11…

Windows11添加用户自定义短语

比如要输入手机号码&#xff0c;直接输入sj就会弹出预先设定好的手机号&#xff0c;也可以预先设置好邮箱&#xff0c;身份证等等&#xff0c;这样就不用输入了 这个咋设置的有时候确实会忘记&#xff0c;所以就记下来了 步骤 第一步 打开设置 时间和语言>语言和区域 第二…

WebRTC的技术原理和使用浅析

一、基本介绍 WebRTC即网页即时通信&#xff0c;是一个支持网页浏览器进行音视频对很多 技术方案。 二、技术特征 1.实时通讯: WebRTc是一项实时通讯技术&#xff0c;允许网络应用或者站点&#xff0c;在不借助中间媒介的情况下&#xff0c;建立浏览器之间点对点的连接&…

Java读取文件内容到字符串

例如当前在D:\\test目录下有一个名为demo.txt的文件&#xff0c;文件里面的内容如下图所示&#xff1a; 第一种方式&#xff1a; 使用BuffererReader 缓冲字符输入流 import lombok.extern.slf4j.Slf4j;import java.io.BufferedReader; import java.io.File; import java.io.…

css对盒模型的理解

面试碰到的一个问题&#xff0c;记录一下 ’ CSS3中的盒模型有以下两种&#xff1a;标准盒子模型、IE盒子模型 盒模型都是由四个部分组成的: 分别是margin、border、padding和content。 标准盒模型和IE盒模型的区别在于设置width和height时&#xff0c;所对应的范围不同&#…

csproj文件常用设置及C#注释常用写法

csproj文件常用设置及C#注释常用写法 .NET新版SDK风格的csproj文件 打开可为空警告 <PropertyGroup><Nullable>enable</Nullable> </PropertyGroup>启动全局引用using 下图没有任何using&#xff0c;仍然不报错 <PropertyGroup><Implicit…

扑克牌最优组合算法题(动态规划+备忘录+快排)

题目如下 题目&#xff1a; 设一副包含点数从A到K,四种花色的52张牌, 将 三张及以上同点数不同花色的牌组 或者三张以及上的同花顺称为 组合, 求出给定一副20张以内的牌中,所能形成的最优的组合列表(最优即组合点数累加最大) 代码要运行正确而且要做输入处理&#xff0c;输出格…

Uncaught TypeError: Illegal invocation

使用console.time报错 console.time将在当前对象(即支持)的上下文中执行&#xff0c;发现一些老的chrome版本中&#xff0c;上下文可能有问题. 解决&#xff1a; 可以使用 console.time.call(window,1111)

关于Easy Mesh

随着网络技术的高速发展&#xff0c;家庭宽带进入了千兆时代&#xff0c;AR&#xff0c;VR&#xff0c;8K影视等高品质产品和智能家居正以前所未有的速度进入寻常百姓家&#xff0c;由于网络覆盖的问题&#xff0c;给WIFI网络应用带来了更大的考验。 WIFI网络覆盖一般是有四种方…

git下载总是报错:身份认证失败的解决办法

在利用git命令下载代码时&#xff0c;提示输入用户名和密码&#xff0c;但是总是显示身份认证失败&#xff0c;在修改密码后仍然没有解决。于是&#xff0c;换了一种方式&#xff0c;采用SSH。 首先在本地生成ssh-key 在虚拟机中执行命令 ssh-keygen -t rsa -C "github…

不再手动PS,教你如何快速删除图片文字!

可以让你快速从照片中提取和复制任何对象的应用。它可以让你轻松地将照片中的物品、人物、动物、文字等放到其他应用中&#xff0c;比如Photoshop、PowerPoint、Word等。ClipDrop还有一个很有用的功能&#xff0c;就是可以去除照片中的文字&#xff0c;让你得到一个干净的背景。…

【MySQL】MySQL数据库基础

目录 一、数据库概念 二、数据库基本使用 1、链接服务器 2、服务器管理 3、使用案例 3.1、创建数据库 3.2、使用数据库 4、服务器&#xff0c;数据库&#xff0c;表关系 三、MySQL架构 四、SQL分类 五、存储引擎 1、存储引擎概念 2、查看存储引擎 3、存储引擎对比…

【强化学习】常用算法之一 “A3C”

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

前端JS一维数组转树状数组并获取当前节点的所有父级名称或id

注意一维数组里面必须要有属性跟父级关联 test(){const list2 [{id: 1,pid: 0,name: 湖南},{id: 2,pid: 1,name: 长沙},{id: 3,pid: 2,name: 雨花区},];// 参数一:需要转树状数组的数组// 参数二:父id// 参数三:当前递归的父级节点name// 参数三:当前递归的父级节点idconst ar…

移远通信再推模组新品,全新5G智能模组SG530C-CN智创全景智慧生活

6月28日&#xff0c;在2023 MWC上海展会首日&#xff0c;移远通信再次宣布推出模组新品。 此次推出的全新5G智能模组SG530C-CN在连接能力、算力、多媒体性能与成本效益等层面都呈现较高水平。该模组将在智慧零售、车载后装、娱乐/直播、手持终端、工业AI等行业与应用场景上大有…

大数据需要一场硬件革命

光子盒研究院 计算领域的进步往往集中在软件上&#xff1a;华丽的应用程序和软件可以跟踪人和生态系统的健康状况、分析大数据&#xff0c;并在智力竞赛中击败人类冠军。与此同时&#xff0c;对支撑所有这些创新的硬件进行全面改革的努力相对来说&#xff0c;略显小众。 自2020…

如何实现MySQL的读写分离?

其实很简单&#xff0c;就是基于主从复制架构&#xff0c;简单来说&#xff0c;就搞一个主库&#xff0c;挂多个从库&#xff0c;然后我们就单 单只是写主库&#xff0c;然后主库会自动把数据给同步到从库上去。 MySQL主从复制原理的是啥&#xff1f; 主库将变更写入 binlog …

架构图的实现过程

项目需求架构图 实现代码 index.vue <template><!-- 外层div --><div class"topu-container" :style"{ minWidth: ${functionDomainList.length * 330}px }"><!-- 头部显示 --><div class"topu-heard"><!-- …