【数据结构】(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 address
	int length;		// maximum number of array
	int 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 large
	travel(&array);
	inverse(&array);	// sort from end to start
	travel(&array);

	append(&array, 66);	// actual length > length,need increase the size of the array
	printf("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 array
	printf("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 element
	arr->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 place
	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)   //  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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

量化交易 - 策略回测

策略回测 1、什么是策略回测&#xff1f;2、策略回测的作用3、策略回测系统概述3.1策略回测中相关的指标介绍3.2量化交易策略的资金容量3.3 完整的策略回测系统包含哪些内容 1、什么是策略回测&#xff1f; 策略回测&#xff0c;也称之为策略回溯测试&#xff0c;是指利用交易…

NLP经典论文研读--xlnet论文代码复现记录

xlnet源码解读(简易pytorch实现版本) xlnet这个模型还是相当复杂的&#xff0c;我看了很长一段时间也还是有很多地方没有搞明白&#xff0c;最后又在网上搜了很多大佬写的相关博客&#xff0c;才算是大致弄明白了&#xff0c;想了解xlnet的原理&#xff0c;请参考原论文&#…

微服务框架中的Eureka和Ribbon的个人理解

微服务框架需要学习的东西很多&#xff0c;基本上我把它分为了五个模块&#xff1a; 第一&#xff1a;微服务技术模块 分为三个常用小模块&#xff1a; 1.微服务治理&#xff1a; 注册发现 远程调用 配置管理 网关路由 2.微服务保护&#xff1a; 流量控制 系统保护 熔断降级 服…

【尚庭公寓SpringBoot + Vue 项目实战】移动端登录管理(二十)

【尚庭公寓SpringBoot Vue 项目实战】移动端登录管理&#xff08;二十&#xff09; 文章目录 【尚庭公寓SpringBoot Vue 项目实战】移动端登录管理&#xff08;二十&#xff09;1、登录业务2、接口开发2.1、获取短信验证码2.2、登录和注册接口2.3、查询登录用户的个人信息 1、…

gbase 8c分布式升级步骤

GBase 8c 多模多态企业级分布式数据库具备高性能、高可用、弹性伸缩、高安全性等特性&#xff0c;可以部署在物理机、虚拟机、容器、私有云和公有云&#xff0c;为关键行业核心系统、互联网业务系统和政企业务系统提供安全、稳定、可靠的数据存储和管理服务。GBase 8c支持行存、…

视频号的视频怎么提取文案?详细教程来啦!

很多人不知道视频号的视频怎么提取文案&#xff0c;今天就和大家详细说说视频号视频提取文案的方法&#xff01; 众所众知视频号的视频无法下载&#xff0c;我们该怎么提取视频号的视频呢&#xff1f; 关于下载视频号的视频&#xff0c;首先给大家两种方案&#xff0c;一种就是…

软考在事业单位可以评高级职称的吗?

导言&#xff1a; 我本人计算机专业&#xff0c;就业于一个事业单位&#xff0c;单位有一个副高级职称数&#xff0c;若干个中级职称数&#xff0c;我可不可以通过软考拿到的中级证书&#xff0c;去找领导申请单位聘我的中级职称&#xff0c;高级职称呢&#xff1f; 以下&…

C++之STL(九)

1、函数对象 什么适合推荐使用函数对象&#xff1f; 需要状态的函数调用: 需要状态的函数调用: 函数对象可以包含成员变量&#xff0c;可以在多次调用中保持状态。这在某些算法中非常有用。 提高性能: 编译器可以更好地优化函数对象&#xff0c;因为它们是具体的类型&#xf…

【路由交换技术】Cisco Packet Tracer基础入门教程(四)

Hello各位&#xff0c;好久不见&#xff0c;第四期我准备讲一下Packet Tracer中DHCP的配置&#xff0c;使用方法。 本章实验我们将拓扑中的某个路由器作为DHCP服务器&#xff08;它仍然可作为路由器使用&#xff09;&#xff0c;通过命令配置DHCP服务。独立的服务器可通过图形化…

基于VUE3+VITE+SpringBoot+Nginx部署项目之跨域配置等问题

前言&#xff1a;遇到问题&#xff0c;解决问题。 第一部分&#xff1a;VUE 配置 1、vite.config.js 文件 server: {proxy: {/api: {target: env.VITE_BASE_URL,changeOrigin: true,secure: false,rewrite: path > path.replace(/^\/api/, )}}}, 2、.env 文件 VITE_BAS…

JavaScript算法之龟兔赛跑

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

UE4 Unlua的快速使用

目录 Unlua的使用前言下载Unlua插件插件安装快速入门语法汇总模块导入多行字符串官方静态方法调用蓝图方法调用重载蓝图中的方法主动调用被重载的蓝图方法输入绑定动态绑定Lua脚本委托容器使用 延迟与协程的使用C 调用Lua 静态导出自定义类型到Lua使用网络UMG资源释放自定义加载…

如何寻找强势货币和弱势货币?

外汇交易的独特之处在于&#xff0c;它融合了两种货币的价值&#xff0c;其中一种货币的价值通过另一种货币来体现。举例来说&#xff0c;USDJPY外汇反映了美元与日元之间的价值关系&#xff0c;而EURUSD则代表了欧元与美元的价值对比。 通过开仓操作&#xff0c;我们预测一种…

继续捡钱,每天几百块!

每日操作计划&#xff1a; 标普信息科技(161128)&#xff0c;溢价8.5%&#xff0c;限购100&#xff0c;一拖七&#xff0c;单户每天700*8.5%59元 印度基金LOF(164824)&#xff0c;溢价2.6%&#xff0c;限购100&#xff0c;一拖七&#xff0c;单户每天700*2.6%18元 美元债LOF(…

如何解决Oracle中PL Developer过期

如果长时间不使用PL Deveploer&#xff0c;再次打开有可能会出现以下页面&#xff1a; 上方页面说明此软件已经过期&#xff0c;有两种方法可以解决上述问题&#xff0c;第一种&#xff1a; 操作注册表&#xff1a; WinR 输入指令“regedit”打开注册表&#xff0c;出现下方页…

List常用操作比for循环更优雅的写法

private String name; //姓名 private Integer age; //年龄 private Integer departId; //所属部门id } List list new ArrayList<>(); 复制代码 简单遍历 使用lamada表达式之前&#xff0c;如果需要遍历list时&#xff0c;一般使用增强for循环&#xff0c;代码如…

利用圆上两点和圆半径求解圆心坐标

已知圆上两点P1&#xff0c;P2&#xff0c;坐标依次为 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1​,y1​),(x2​,y2​)&#xff0c;圆的半径为 r r r&#xff0c;求圆心的坐标。 假定P1&#xff0c;P2为任意两点&#xff0c;则两点连成线段的中点坐标是 x m i …

Python学习笔记24:进阶篇(十三)常见标准库使用之数据压缩功能模块zlib,gzip,bz2,lzma的学习使用

前言 本文是根据python官方教程中标准库模块的介绍&#xff0c;自己查询资料并整理&#xff0c;编写代码示例做出的学习笔记。 根据模块知识&#xff0c;一次讲解单个或者多个模块的内容。 教程链接&#xff1a;https://docs.python.org/zh-cn/3/tutorial/index.html 数据压缩…

活动|华院计算受邀参加2024全球人工智能技术大会(GAITC),探讨法律大模型如何赋能社会治理

6月22至23日&#xff0c;备受瞩目的2024全球人工智能技术大会&#xff08;GAITC&#xff09;在杭州市余杭区未来科技城隆重举行。本届大会以“交叉、融合、相生、共赢”为主题&#xff0c;集“会、展、赛”为一体&#xff0c;聚“产、学、研”于一堂。值得一提的是&#xff0c;…

如何在线上快速定位bug(干货)

想必有许多人都想我刚进公司一样不会快速定位线上bug吧&#xff0c;不会快速定位bug会大大降低我们的开发效率&#xff0c;随之而来的就是工作质量下降、业绩下滑。 我总结了一些我常用的线上定位技巧&#xff0c;希望能帮助到大家&#xff01; 我这里以使用阿里云日志分析作…