【数据结构】(C语言):动态数组

动态数组:

  • 内存区域连续,即每个元素的内存地址连续。
  • 可用索引查看元素,数组[索引号]。
  • 指定位置删除元素,该位置之后的元素全部往前移动一位。
  • 指定位置添加元素,从最后到该位置的元素全部往后移动一位。
  • 物理大小:创建数组时,指定的容量大小。逻辑大小:实际已使用的容量大小。
  • 扩容:数组满时,扩大数组的内存空间。(方法:开辟新的内存空间,将原数组内容复制到新的内存区域。)
  • 缩容:数组使用容量远小于数组物理大小时,缩小数组的内存空间。(方法:开辟新的内存空间,将原数组内容复制到新的内存区域。)


C语言实现:

创建结构体数据类型:

typedef struct Array
{int *p;			// 数组地址,即连续内存地址的首地址int length;		// 数组物理大小,即最大容纳多少元素int n;			// 数组逻辑大小,即实际存储多少元素
}Array;        	    // 别名

创建数组变量: 

Array array;

初始化数组:

void init(Array *arr, int len)
{arr->p = (int *)malloc(len * sizeof(int));    // 分配数组内存空间if(arr->p == NULL){perror("Memory allocation failed");exit(-1);}arr->length = len;                            // 指定数组物理大小arr->n = 0;                                   // 逻辑大小初始化为0
}

扩容、缩容:

使用realloc动态分配内存空间,若分配新内存,会将内容复制到新地址。

void resize(Array *arr, int len)
{int *t = (int *)realloc(arr->p, len * sizeof(int));// for(int k = 0; k < arr->n; k++)// {// 	t[k] = arr->p[k];// }arr->p = t;arr->length = len;
}

添加元素:

若数组满,扩容(本文为内存空间扩大一倍)。

// 在数组尾部添加
void append(Array *arr, int data)
{if(arr->length == arr->n)		// 若数组满,扩容一倍{int newlength = arr->length * 2;	resize(arr, newlength);}arr->p[arr->n] = data;arr->n++;                    // 每添加一个元素,逻辑大小+1
}
// 在数组指定位置添加元素
void insert(Array *arr, int i, int data)
{if(arr->length == arr->n)		// 数组满,扩容一倍{int newlength = arr->length * 2;resize(arr, newlength);}if(i < 0 || i > arr->n)         // 检查索引号是否越界{perror("index out of bounds");return ;}// 从最后一个元素到指定位置元素都要往后移动一位,空出位置给新元素int k;for(k = arr->n - 1; k >= i; k--){arr->p[k+1] = arr->p[k];}arr->p[k + 1] = data;arr->n++;
}

删除元素:

若数组实际存储数据小于物理大小的一半,缩容(本文将内存空间缩小一半但不小于4)。

// 从数组尾部删除元素
int pop(Array *arr)
{if(arr->n == 0) return -1;int value = arr->p[arr->n - 1];arr->n--;                         // 每删除一个元素,逻辑大小-1// 若实际数据<物理大小一半,缩容,但物理大小不小于4	if(arr->n < ceil(arr->length / 2) && arr->length > 4){int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}
// 在数组指定位置删除元素
int del(Array *arr, int i)
{if(i < 0 || i > arr->n || arr->n == 0)   // 检查索引号是否越界{perror("index out of bounds");exit(-1);}int value = arr->p[i];		// 从指定位置到最后的元素都要往前移动一位for(int k = i; k < arr->n; k++){arr->p[i] = arr->p[i+1];}arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4)   //  达到条件,缩容{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}

遍历数组元素,获取指定位置元素:

// 遍历数组元素
void travel(Array *arr)
{if(arr->n == 0) return ;printf("elements: ");for(int k = 0; k < arr->n; k++){printf("%d  ", arr->p[k]);}printf("\n");
}
// 获取指定位置元素
int get(Array *arr, int i)
{if(i < 0 || i > arr->n || arr->n == 0)    // 检查索引号是否越界{perror("index out of bounds");exit(-1);}return arr->p[i];
}

排序(从小到大),倒置(从最后到开头):

// 排序(从小到大,冒泡排序,还有其他排序方法此处省略)
void sort(Array *arr)
{int x = 0;for(int k = arr->n-1; k > 0; k--){for(int i = 0; i < k; i++){if(arr->p[i] > arr->p[i+1]){int tmp = arr->p[i];arr->p[i] = arr->p[i+1];arr->p[i+1] = tmp;x = 1;}}if(x == 0) break;}
}
// 倒置(从最后到开头)
void inverse(Array *arr)
{if(arr->n == 0) return;for(int i = 0, k = arr->n-1; i < k; i++, k--){int tmp = arr->p[i];arr->p[i] = arr->p[k];arr->p[k] = tmp;}
}


完整代码:(array.c)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>/* structure */
typedef struct Array		// array structure
{int *p;			// array memory addressint length;		// maximum number of arrayint n;			// actual number of array
}Array;/* function prototype */
void init(Array *, int);		// array initialization
void resize(Array *, int);		// increase or reduce the size of the array
void append(Array *, int);		// add element to the end of the array
void insert(Array *, int, int);		// add element to the specify location(start with 0)
void travel(Array *);			// show element one by one
int pop(Array *);			// delete element from the end of the array
int del(Array *, int);			// delete element from the specify location of the array
int get(Array *, int);			// show element at the specify location(start with 0)
void sort(Array *);			// sort array from small to large
void inverse(Array *);			// sort array form end to start/* main function */
int main(void)
{Array array;init(&array, 4);printf("lenght is %d, actual is %d\n", array.length, array.n);append(&array, 2);append(&array, 9);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);insert(&array, 1, 12);insert(&array, 0, 25);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);get(&array, 2);		// get element that index=2(start with 0)sort(&array);		// sort from small to largetravel(&array);inverse(&array);	// sort from end to starttravel(&array);append(&array, 66);	// actual length > length,need increase the size of the arrayprintf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);del(&array, 3);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);pop(&array);		// actual length < length/2,need reduce the size of the arrayprintf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);pop(&array);pop(&array);pop(&array);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);return 0;
}/* subfunction */
void init(Array *arr, int len)		// array initialization
{arr->p = (int *)malloc(len * sizeof(int));if(arr->p == NULL){perror("Memory allocation failed");exit(-1);}arr->length = len;arr->n = 0;
}void resize(Array *arr, int len)		// increase or reduce the size of the array
{int *t = (int *)realloc(arr->p, len * sizeof(int));//for(int k = 0; k < arr->n; k++)//{//	t[k]= arr->p[k];//}arr->p = t;arr->length = len;	
}void append(Array *arr, int data)		// add element to the end of the array
{if(arr->length == arr->n)		// if array is full, expand the array to double size{int newlength = arr->length * 2;	resize(arr, newlength);}arr->p[arr->n] = data;arr->n++;
}void insert(Array *arr, int i, int data)	// add element to the specify location(start with 0)
{if(arr->length == arr->n)		// if array is full, expand the array to double size{int newlength = arr->length * 2;resize(arr, newlength);}if(i < 0 || i > arr->n){perror("index out of bounds");return ;}int k;for(k = arr->n - 1; k >= i; k--)	// from end to i,each element move back a place{arr->p[k+1] = arr->p[k];}arr->p[k + 1] = data;			// leave an empty slot for the new elementarr->n++;
}void travel(Array *arr)			// show element one by one
{if(arr->n == 0) return ;printf("elements: ");for(int k = 0; k < arr->n; k++){printf("%d  ", arr->p[k]);}printf("\n");
}int pop(Array *arr)			// delete element from the end of the array
{if(arr->n == 0) return -1;int value = arr->p[arr->n - 1];arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4)   //  reduce the size of array{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}int del(Array *arr, int i)		// delete element from the specify location of the array
{if(i < 0 || i > arr->n || arr->n == 0){perror("index out of bounds");exit(-1);}int value = arr->p[i];		// from i to end,each element move forward one placefor(int k = i; k < arr->n; k++){arr->p[i] = arr->p[i+1];}arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4)   //  reduce the size of array{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}int get(Array *arr, int i)		// show element at the specify location(start with 0)
{if(i < 0 || i > arr->n || arr->n == 0){perror("index out of bounds");exit(-1);}return arr->p[i];
}void sort(Array *arr)			// sort array from small to large
{int x = 0;for(int k = arr->n-1; k > 0; k--){for(int i = 0; i < k; i++){if(arr->p[i] > arr->p[i+1]){int tmp = arr->p[i];arr->p[i] = arr->p[i+1];arr->p[i+1] = tmp;x = 1;}}if(x == 0) break;}
}void inverse(Array *arr)		// sort array form end to start
{if(arr->n == 0) return;for(int i = 0, k = arr->n-1; i < k; i++, k--){int tmp = arr->p[i];arr->p[i] = arr->p[k];arr->p[k] = tmp;}
}

编译链接: gcc -o array array.c

执行可执行文件: ./array

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

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

相关文章

冷门赛道,视频号励志语录赛道详解,新手轻松上手

大家好&#xff0c;我是闷声轻创&#xff0c;在当今数字化时代&#xff0c;社交媒体已成为人们获取信息、分享生活和实现个人价值的重要渠道。视频号&#xff0c;作为新兴的短视频平台&#xff0c;以其独特的优势和巨大的流量潜力&#xff0c;吸引了众多创作者的目光。今天我将…

防近视台灯有效果吗?专业护眼台灯推荐!告诉你台灯怎么选

随着学业负担的加重和电子设备的广泛普及&#xff0c;近视问题在青少年群体中愈发凸显&#xff0c;近视率持续走高。导致近视的因素错综复杂&#xff0c;除了过度使用手机外&#xff0c;遗传因素、不良的用眼习惯、环境因素、营养不均衡以及学习压力等均为重要因素&#xff0c;…

c++习题01-ljc的暑期兼职

目录 一&#xff0c;题目描述 二&#xff0c;思路 三&#xff0c;伪代码 四&#xff0c;流程图 五&#xff0c;代码 一&#xff0c;题目描述 二&#xff0c;思路 1&#xff0c;根据题目要求需要声明4个变量&#xff1a;a,b,c,d ;牛奶价格a&#xff0c;活动要求b&…

Advantest 93000测试机中CLOCK DOMAIN 详解

爱德万测试&#xff08;Advantest&#xff09;的V93000系列测试系统是一个高度模块化和可扩展的平台&#xff0c;专为复杂和高性能的半导体器件测试而设计&#xff0c;包括系统级芯片&#xff08;SoC&#xff09;、存储器、射频&#xff08;RF&#xff09;和混合信号器件等。在…

C++语法20 一维数组及其相关问题详解

这是《C算法宝典》语法入门篇的第20节文章啦~ 如果你之前没有太多C基础&#xff0c;请点击&#x1f449;专栏&#xff1a;C语法入门&#xff0c;如果你C语法基础已经炉火纯青&#xff0c;则可以进阶算法&#x1f449;专栏&#xff1a;算法知识和数据结构&#x1f449;专栏&…

基于Java的宠物领养管理系统【附源码】

摘 要 近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;宠物管理系统利用计算机网络实现信息化管理&#xff0c;使整个宠物领养的发展和服务水平有显著提升。 本文拟采用IDEA开发工具…

ELK集群设置密码

一、软件安装清单 elasticsearch7.17.22logstash7.17.22kibana:7.17.22filebeat7.17.22elasticsearch-head:5 二、配置 生成证书 进入elasticsearch容器 bin/elasticsearch-certutil cert -out /usr/share/elasticsearch/config/elastic-certificates.p12 -pass将证书拷贝…

探秘10个顶尖设计的秘密

本文为大家盘点了 10 个优秀的个人网页作品&#xff0c;均来自于即时设计的资源广场。网页设计往往是一个复杂的过程&#xff0c;从前期的调研整理到后来的设计制作&#xff0c;往往需要设计师们投入大量的心血。今天就为大家分享来自即时设计的 10 个不同类型的优秀网页作品&a…

LangChain入门学习笔记(六)—— Model I/O之Output Parsers

当大模型产生输出返回后&#xff0c;它的内容更像是一段平铺的文字没有结构。在传给下游节点处理时可能并不能符合输入要求&#xff0c;LangChain提供了一套机制使得模型返回的内容可以按照开发者定义的那样结构化。 在官网文档中可以看到LangChain提供了丰富的输出解析器&…

Ngnix内存池——高并发实现高效内存管理

目录 一、高并发下传统方式的弊端 1、常用的内存操作函数 2、弊端一 3、弊端二 4、弊端三 5、弊端四 二、弊端解决之道 1、内存管理维度分析 2、内存管理组件选型 三、高并发内存管理最佳实践 1、内存池技术 2、内存池如何解决弊端 3、高并发内存池如何实现 四、…

Vue 学习之 axios

目录 执行安装命令&#xff1a;npm install axios 使用的时候导入 axios以data&#xff0c;params&#xff0c;headers传参方式的区别 axios封装 是一个基于 promise 的 网络请求库&#xff0c;作用于浏览器和 node.js 中。使用Axios可以在前端项目中发送各种方式的HTTP请求…

最新AI智能聊天对话问答系统源码(图文搭建部署教程)+AI绘画,文生图,TTS语音识别输入,文档分析

一、人工智能语言模型和AI绘画在多个领域广泛应用 人工智能语言模型和AI绘画在多个领域都有广泛的应用。以下是一些它们的主要用处&#xff1a; 人工智能语言模型 内容生成 写作辅助&#xff1a;帮助撰写文章、博客、报告、剧本等。 代码生成&#xff1a;自动生成或补全代码&…

迭代器模式观察者模式

文章目录 1.引出迭代器模式1.展示院系结构2.传统方式 2.迭代器模式解决院系结构展示问题1.基本介绍2.原理类图3.类图4.代码实现1.Department.java 存储信息的对象2.College.java 被迭代的类型接口3.ComputerCollege.java 被迭代的具体实现类&#xff0c;存储数据并将其在创建迭…

PAL: Program-aided Language Models

PAL: Program-aided Language Models ArXiv&#xff1a;https://arxiv.org/pdf/2211.10435 GitHub&#xff1a;https://reasonwithpal.com/ 一、动机 大模型与Chain-of-Thought可以很好地将一些复杂的问题分解为若干个子问题并进行逐步推理&#xff1b;但是对于一些较为复杂…

JavaScript算法之龟兔赛跑

简介:龟兔赛跑算法,又称弗洛伊德循环检测算法,是一种在链表中非常常用的算法。它基于运动学和直觉的基本定律。本文旨在向您简要介绍该算法,并帮助您了解这个看似神奇的算法。 假设高速公路上有两辆车。其中一辆的速度为 x,另一辆的速度为 2x。它们唯一能相遇的条件是它们…

个人支付系统实现

基础首页&#xff1a; 订单&#xff1a; 智能售卡系统 基于webmanworkerman开发 禁用函数检查 使用这个脚本检查是否有禁用函数。命令行运行curl -Ss https://www.workerman.net/check | php 如果有提示Function 函数名 may be disabled. Please check disable_functions in …

2024年6月17日~2024年6月26日周报

一、前言 在上周主要完成了可变形卷积的学习的部署。 本周&#xff0c;结合前段时间的工作与闵老师的讨论&#xff0c;思考了接下来的一些尝试方向。本周重新在之前的网络上尝试添加可变形卷积v4&#xff0c;或者将可变形卷积v2修改为可变形卷积v4。另外&#xff0c;继续学习了…

java中的Collections工具类

Collections类是java中提供的一个工具类&#xff0c;它和接口Collection乍一看非常相像&#xff0c;但是二者的区别是非常大的&#xff0c;最明显的就是它们一个是类&#xff0c;而另一个是接口了。Collections工具类的作用是对Set 、Map、 List这些容器提供辅助方法来对容器中…

Springboot + Mybatis-Plus代码生成指南

使用 Spring Boot 和 MyBatis-Plus 生成代码&#xff0c;可以大大简化开发流程&#xff0c;可以保持编码的规范性&#xff0c;生成单元测试等。以下是详细步骤&#xff1a; 配置pom.xml <dependency><groupId>com.baomidou</groupId><artifactId>myb…

4.1 四个子空间的正交性

一、四个子空间的正交性 如果两个向量的点积为零&#xff0c;则两个向量正交&#xff1a; v ⋅ w v T w 0 \boldsymbol v\cdot\boldsymbol w\boldsymbol v^T\boldsymbol w0 v⋅wvTw0。本章着眼于正交子空间、正交基和正交矩阵。两个子空间的中的向量&#xff0c;一组基中的向…