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

news2024/9/20 20:34:16

动态数组:

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


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

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

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

相关文章

自费5K,测评安德迈、小米、希喂三款宠物空气净化器谁才是高性价比之王

最近&#xff0c;家里的猫咪掉毛严重&#xff0c;简直成了一个活生生的蒲公英&#xff0c;家中、空气中各处都弥漫着猫浮毛甚至所有衣物都覆盖着一层厚厚的猫毛。令人难以置信的是&#xff0c;有时我甚至在抠出的眼屎中都能发现夹杂着几根猫毛。真的超级困扰了。但其实最空气中…

句法分析概述

第1关&#xff1a;句法分析概述 任务描述 本关任务&#xff1a;通过对句法分析基本概念的学习&#xff0c;完成相应的选择题。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 句法分析的基础概念&#xff1b; 句法分析的数据集和评测方法。 句法分析简介…

ubuntu如何切换到root用户

1、主要指令&#xff1a; sudo -i su root 2、示例 3、其他说明 在Ubuntu&#xff08;以及大多数其他基于Linux的操作系统中&#xff09;&#xff0c;切换到root用户通常意味着获得了对系统的完全访问权限。这种权限允许执行以下操作&#xff08;但不限于这些&#xff09;…

深度学习论文: Surge Phenomenon in Optimal Learning Rate and Batch Size Scaling

深度学习论文: Surge Phenomenon in Optimal Learning Rate and Batch Size Scaling Surge Phenomenon in Optimal Learning Rate and Batch Size Scaling PDF:https://arxiv.org/pdf/2405.14578 PyTorch: https://github.com/shanglianlm0525/PyTorch-Networks 1 概述 本文研…

使用Python进行Socket接口测试

大家好&#xff0c;在现代软件开发中&#xff0c;网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯&#xff0c;都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中&#xff0c;Socket&#xff08;套接字&#xff09;技术扮演了重要角色…

2024 6.17~6.23 周报

一、上周工作 吴恩达的机器学习、实验-回顾之前密集连接部分 二、本周计划 继续机器学习&#xff0c;同时思考实验如何修改&#xff0c;开始整理代码 三、完成情况 3.1 多类特征、多元线性回归的梯度下降、特征缩放、逻辑回归 多类特征&#xff1a; 多元线性回归的梯度下…

基于PHP的长城景区信息管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的长城景区信息管理系统 一 介绍 此长城景区信息管理系统基于原生PHP开发&#xff0c;数据库mysql。系统角色分为用户和管理员。 技术栈&#xff1a;phpmysqlphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 浏览长城景区信息(旅…

出手便是王炸,曙光存储将高端存储推向新高度

二十年磨一剑&#xff0c;今朝试锋芒。 近日&#xff0c;曙光存储重磅发布全球首个亿级IOPS集中式全闪存储FlashNexus&#xff0c;正式宣告进入高端存储市场。 作为存储产业皇冠上的明珠&#xff0c;高端存储一向以技术难度大、市场准入门槛高和竞争格局稳定著称&#xff0c;…

React的Props、生命周期

Props 的只读性 “Props” 是 React 中用于传递数据给组件的一种机制&#xff0c;通常作为组件的参数进行传递。在 React 中&#xff0c;props 是只读的&#xff0c;意味着一旦将数据传递给组件的 props&#xff0c;组件就不能直接修改这些 props 的值。所以组件无论是使用函数…

Studying-代码随想录训练营day22| 回溯理论基础、77.组合、216.组合总和II、17.电话号码的字母组合

第22天&#xff0c;回溯章节开始&#xff01;一大算法难点&#xff0c;加油加油&#xff01; 回溯理论基础组合问题的剪枝操作 文档讲解&#xff1a;代码随想录回溯理论基础 视频讲解&#xff1a;回溯理论基础 回溯法也叫回溯搜索法&#xff0c;它是一种搜索&#xff0c;遍历的…

数值稳定性、模型初始化和激活函数

一、数值稳定性&#xff1a;神经网络很深的时候数据非常容易不稳定 1、神经网络梯度 h^(t-1)是t-1层的输出&#xff0c;也就是t层的输入&#xff0c;y是需要优化的目标函数&#xff0c;向量关于向量的倒数是一个矩阵。 2、问题&#xff1a;梯度爆炸、梯度消失 &#xff08;1&…

leetcode-19-回溯

引自代码随想录 [77]组合 给定两个整数 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4]] 1、大致逻辑 k为树的深度&#xff0c;到叶子节点的路径即为一个结果 开始索引保证不重复…

当了面试官才知道:做好这3点,面试成功率至少提高50%

关于辉哥&#xff1a; 资深IT从业者&#xff0c; 曾就职于阿里、腾讯、美团、中信科等互联网公司和央企&#xff1b; 两岁小男孩的父亲。 不定期分享职场 | 婚姻 | 育儿 | 个人成长心得体会 关注我&#xff0c;一起学习和成长。 最近作为公司社招面…

一文入门CMake

我们前几篇文章已经入门了gcc和Makefile&#xff0c;现在可以来玩玩CMake了。 CMake和Makefile是差不多的&#xff0c;基本上是可以相互替换使用的。CMAke可以生成Makefile&#xff0c;所以本质上我们还是用的Makefile&#xff0c;只不过用了CMake就不用再写Makefile了&#x…

Zookeeper 四、Zookeeper应用场景

Zookeeper是一个典型的发布/订阅模式的分布式数据管理与协调框架&#xff0c;我们可以使用它来进行分布式数据的发布与订阅。另一方面&#xff0c;通过对Zookeeper中丰富的数据节点类型进行交叉使用&#xff0c;配合Watcher事件通知机制&#xff0c;可以非常方便地构建一系列分…

Day.js

Day.js 是什么&#xff1f; Day.js是一个极简的JavaScript库&#xff0c;可以为现代浏览器解析、验证、操作和显示日期和时间。 Day.js中文网 为什么要使用Day.js &#xff1f; 因为Day.js文件只有2KB左右&#xff0c;下载、解析和执行的JavaScript更少&#xff0c;为代码留下更…

如何避免爬取网站时IP被封?

互联网协议 (IP) 地址是识别网络抓取工具的最常见方式。IP 是每个互联网交换的核心&#xff0c;对其进行跟踪和分析可以了解很多有关连接客户端的信息。 在网络抓取中&#xff0c;IP 跟踪和分析&#xff08;又名指纹&#xff09;通常用于限制和阻止网络抓取程序或其他不需要的访…

配电房挂轨巡检机器人

配电房作为电网中的重要组成部分。其运行的的安全和稳定性直接影响到电力供应的质量。然而&#xff0c;传统的人工巡检模式存在诸多弊端&#xff0c;例如巡检效率低下、人员安全难以保障、巡检结果主观性强等问题。为了解决这些问题&#xff0c;旗晟机器人推出B3系列升降云台轨…

浅谈LiveData的通知过程

浅谈 LiveData 的通知机制 LiveData 和 ViewModel 一起是 Google 官方的 MVVM 架构的一个组成部分。巧了&#xff0c;昨天分析了一个问题是 ViewModel 的生命周期导致的。今天又遇到了一个问题是 LiveData 通知导致的。而 ViewModel 的生命周期和 LiveData 的通知机制是它们的…

AI绘图软件:设计师的创意加速器

在人工智能的浪潮中&#xff0c;AI绘图软件工具已成为设计师和创意工作者的得力助手&#xff0c;它们不仅加速了复杂绘图任务的完成&#xff0c;还激发了无限创意。本文将为您介绍几款AI绘图软件工具&#xff0c;它如何成为提升工作效率和创意灵感的关键。 1. StartAI&#xf…