【数据结构】(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.mzph.cn/diannao/36619.shtml

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

相关文章

【保姆级讲解ECMAScript和JavaScript之间的区别】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

全面国产化信创适配改造方案说明

一、概叙 系统的全面国产化适配改造需要从多个方面进行考虑&#xff0c;改造前需要进行充分的论证&#xff0c;在满足具体业务场景的前提下&#xff0c;以确保系统的稳定性和安全性&#xff0c;同时还要考虑技术的发展&#xff0c;不断优化和更新。因此全面国产化适配改造也面临…

AI 开发平台(Coze)搭建《AI女友(多功能版本)》

前言 本文讲解如何从零开始&#xff0c;使用扣子平台去搭建《AI女友&#xff08;多功能版本&#xff09;》 bot直达&#xff1a;AI女友&#xff08;多功能版&#xff09; - 扣子 AI Bot (coze.cn) 欢迎大家前去体验&#xff01;&#xff01;&#xff01; 正文 功能介绍 …

系统架构师考点--系统配置与性能评价

大家好。今天我们来总结一下系统配置与性能评价的考点内容&#xff0c;这一部分一般是出在上午场的选择题中&#xff0c;占1-2分左右。 一、性能指标 计算机 对计算机评价的主要性能指标有&#xff1a;时钟频率(主频)&#xff1b;运算速度&#xff1b;运算精度内存的存储容量…

ManageEngine连续荣登Gartner 2024年安全信息和事件管理魔力象限

我们很高兴地宣布&#xff0c;ManageEngine再次在Gartner的安全信息和事件管理&#xff08;SIEM&#xff09;魔力象限中榜上有名&#xff0c;这是我们连续第七年获得这一认可。 Gartner ManageEngine Log360是一款全面的SIEM解决方案&#xff0c;旨在帮助组织有效处理日志数据…

cuda 学习笔记4

一 基本函数 在GPU上开辟空间&#xff0c;无论定义的数据是float还是int ,还是****gpu_int,分配空间的函数都是下面固定的形式 (void**)& 1.函数定义&#xff0c;global void 是配套使用的&#xff0c;是在GPU上定义&#xff0c;也就是GPU上执行&#xff0c;CPU上调用的函数…

python pyautogui.position实时输出坐标

import pyautogui import timewhile True:# 获取鼠标当前坐标x, y pyautogui.position()# 打印坐标print(f"当前坐标&#xff1a;({x}, {y})")# 暂停1秒time.sleep(1) 输出实时鼠标位置坐标

62.指针和二维数组(2)

一.指针和二维数组 1.如a是一个二维数组&#xff0c;则数组中的第i行可以看作是一个一维数组&#xff0c;这个一维数组的数组名是a[i]。 2.a[i]代表二维数组中第i行的首个元素的地址&#xff0c;即a[i][0]的地址。 二.进一步思考 二维数组可以看作是数组的数组&#xff0c;本…

springboot+vue+mybatis母婴二手销售系统+PPT+论文+讲解+售后

目前由于我国二手销售的规模较小,同发达国家相比,二手销售比重始终偏低,消费总额增长缓慢,进一步抑制了市场消费的提升,随着市场竞争的日益激烈,虽然许多商家主动选用二手销售模式,但却缺乏对其充分的重视与销售风险的良性控制,一些商家没有建立独立的信用实践管理部门,无法在交…

linux使用docker部署kafka集群

1、拉取kafka docker pull wurstmeister/kafka docker pull wurstmeister/zookeeper 2、创建网络 docker network create app-kafka 3、启动zookeeper docker run -d \--name zookeeper \-p 2181:2181 \--network app-kafka \--restart always \wurstmeister/zookeeper …

【ISAC】通感一体化讲座(刘凡)

高斯信道下通信感知一体化的性能极限(刘凡) 文章目录 背景背景 通信和感知在硬件结构上相似,高效地利用资源,实现相互的增益; 感知是基于不同的任务,比如目标检测(检测概率,虚警概率),估计任务(从收到的信号中去估计有用的参数,均方误差,CRB),识别(知道目标的…

Str.format()方法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 在Python2.6之后&#xff0c;提供了字符串的format()方法对字符串进行格式化操作。format()功能非常强大&#xff0c;格式也比较复杂&…

基于ADRC自抗扰算法的UAV飞行姿态控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 控制系统概述 4.2 ADRC基本框架 4.3 控制律设计 5.完整工程文件 1.课题概述 基于ADRC自抗扰算法的UAV飞行姿态控制系统simulink建模与仿真&#xff0c;分别对YAW&#xff0c;PITCH&#xff0c;ROL…

K-Means 算法详解

K-Means 是一种常用的无监督学习算法&#xff0c;广泛应用于数据聚类分析。本文将详细讲解 K-Means 算法的原理、步骤、公式以及 Python 实现&#xff0c;帮助你深入理解这一经典算法。 什么是 K-Means 算法&#xff1f; K-Means 算法是一种基于原型的聚类算法&#xff0c;其…

Linux分区以及磁盘管理

目录 一、磁盘 1.磁盘结构 1.1物理结构 1.2数据结构 2.1磁盘容量 2.2磁盘接口类型 2.磁盘分区的表示 3.MBR与磁盘分区表示 4.磁盘分区结构 二、文件系统 1、类型 三、命令 1.检测并确认新硬盘 2.创建系统文件(格式化) 2.1mkfs命令 2.2SWAP 3.挂载、卸载文件系统…

Simulink中三相PMSM配置及使用

1. 模块介绍 Simulink提供了专门用于电力系统仿真&#xff0c;包括电机的动态建模和控制的电机模型&#xff0c;其中&#xff0c;永磁同步电机模块 Permanent Magnet Synchronous Machine 支持实现三相或五相永磁同步电机模拟&#xff0c;电机绕组采用星型连接&#xff0c;在这…

【图像分类】Yolov8 完整教程 |分类 |计算机视觉

目标&#xff1a;用YOLOV8进行图像分类。 图像分类器。 学习资源&#xff1a;https://www.youtube.com/watch?vZ-65nqxUdl4 努力的小巴掌 记录计算机视觉学习道路上的所思所得。 1、文件结构化 划分数据集&#xff1a;train,val,test 知道怎么划分数据集很重要。 文件夹…

应用图扑 HT for Web 搭建拓扑关系图

拓扑结构在计算机网络设计和通信领域中非常重要&#xff0c;因为它描述了网络中的设备&#xff08;即“点”&#xff09;如何相互连接&#xff08;即通过“线”&#xff09;。这种结构不仅涉及物理布局&#xff0c;即物理拓扑&#xff0c;还可以涉及逻辑或虚拟的连接方式&#…

【系统架构设计师】计算机组成与体系结构 ③ ( 层次化存储结构 | 寄存器 | 高速缓存 | 内存 | 外存 )

文章目录 一、层次化存储结构1、层次化存储结构2、层次化存储结构 - 示例说明3、程序员可操作的部分 计算机 采用 分级存储结构 , 主要目的是 为了 解决 容量 / 价格 / 速度 之间的矛盾 ; 一、层次化存储结构 1、层次化存储结构 计算机 存储器 按照存储速度 由快到慢 进行排序 …

吐血推荐!3款视频生成工具,全部国产,都免费

AI视频大模型的爆发&#xff0c;让创作爆款视频不再是专业人士的能力。 今天二师兄给大家推荐3款免费的视频生成工具。 01 可灵 推荐指数 &#xff1a; 五颗星 先看效果 可灵大模型测试 可灵大模型是快手AI团队自主研发的视频生成大模型&#xff0c;具备强大的视频创作能力&a…