动态数组C语言实现详解

article/2025/10/3 15:15:00

目录

0、前言

一、动态数组数据结构

二、动态数组增删改查函数声明

三、数组创建

1、头部动态创建

2、头部静态创建

四、元素添加

五、元素删除

1、根据元素值删除

2、根据元素位置删除

六、元素修改

七、元素查找

八、数组清空

九、数组销毁

十、验证程序


0、前言

线性表(Linear List)。顾名思义,线性表就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。其实除了数组,链表、队列、栈等也是线性表结构。

非线性表。在非线性表中,数据之间并不是简单的前后关系

数组(Array)。是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。最大的特点就是支持随机访问,但插入、删除操作也因此变得比较低效,平均情况时间复杂度为 O(n)

一、动态数组数据结构

struct dstrct_array
{unsigned int size; /* array total size */unsigned int used; /* array used size, from 1 to size */unsigned int tpsz; /* data type size */void *p; /* array, dynamically applied by array_init()*/
};

二、动态数组增删改查函数声明

extern struct dstrct_array* array_creat(unsigned int size, unsigned int tpsz);
extern int array_init(struct dstrct_array *array, unsigned int size, unsigned int tpsz);
extern int array_insert (struct dstrct_array *array, unsigned int pos, void *const value);
extern int array_del_value (struct dstrct_array *array, void *value);
extern int array_del_pos   (struct dstrct_array *array, unsigned int pos);
extern int array_modify    (struct dstrct_array *array, unsigned int pos, void *const value);
extern int array_search_pos(struct dstrct_array *array, void* const value);
extern int array_empty  (struct dstrct_array *array);
extern int array_destroy(struct dstrct_array *array);extern unsigned int array_used(struct dstrct_array *array);
extern unsigned int array_size(struct dstrct_array *array);extern void algo_array_test(void);

三、数组创建

1、头部动态创建

/*** dynamically create a dynamic array, including the array header and data space.* * @param size: array size* @param tpsz: array data type length* @return NULL:malloc fail*        !NULL:success*/
struct dstrct_array* array_creat(unsigned int size, unsigned int tpsz)
{struct dstrct_array *array = NULL;if (size <= 0 || tpsz <= 0)return NULL;/* malloc an array control struct */array = ARRAR_MALLOC(sizeof(*array));if (array == NULL){return NULL;}/* calloc an array */void *p = ARRAR_CALLOC(1, (size * tpsz));if (p == NULL)return NULL;array->used = 0;array->size = size;array->tpsz = tpsz;array->p = p;return array;
}

2、头部静态创建

/*** init a dynamic array, malloc a data space.* * @param array: * @param size: array size* @param tpsz: array data type length* @return -1:array is null or malloc fail*          0:success*/
int array_init(struct dstrct_array *array, unsigned int size, unsigned int tpsz)
{if (array == NULL)return -1;/* calloc an array */void *p = ARRAR_CALLOC(1, (size * tpsz));if (p == NULL)return -1;array->used = 0;array->size = size;array->tpsz = tpsz;array->p = p;return 0;
}

四、元素添加

/*** insert a value to an array.* @note The array cannot be inserted after it is full, *       and can only be inserted when the used is less than the size*       The purpose is to leave at least one space for carrying* @param array: * @param pos: 1 - size* @param value: data* @return -1:array is null*         -2:pos overstep the boundary of array*         -3:used is greater than size*          0:success*/
int array_insert(struct dstrct_array *array, unsigned int pos, void *const value)
{char *pbegin = NULL;void *pnew = NULL, *pold = NULL, *pinsert = NULL;unsigned int i = 0;if (array == NULL)return -1;/* adjust the pos did cross the array*/if (pos > array->size || pos <= 0)return -2;/* adjust used is not greater than size */if (array->used >= array->size)return -3;/* move the array data back one cell */pbegin = array->p;for (i=array->used; i>=pos; i--){pnew = pbegin + i * array->tpsz;pold = pbegin + (i - 1) * array->tpsz;memcpy(pnew, pold, array->tpsz);}/* insert the data*/pinsert = pbegin + (pos - 1) * array->tpsz;memcpy(pinsert, value, array->tpsz);array->used++;return 0;
}

五、元素删除

1、根据元素值删除

/*** delete the array data by value.** @param array: delete array* @param value: delete value* @return -1:array is null*         -2:value is not matched*          0:success*/
int array_del_value(struct dstrct_array *array, void *value)
{char *pbegin = NULL;void *pnew = NULL, *pold = NULL;int i = 0, res = 0;int check_flag = 1, check_succ = 0;if (array == NULL)return -1;pbegin = array->p;for (i=0; i<array->used; i++){/* Check the match value */if (check_flag){res = memcmp(pbegin + i * array->tpsz, value, array->tpsz);if (res == 0){check_flag = 0;check_succ = 1;}}/* delete the check value and move one cell forward*/else{pnew = pbegin + (i - 1) * array->tpsz;pold = pbegin + i * array->tpsz;memcpy(pnew, pold, array->tpsz);}}/* match and deleat success*/if (check_succ){array->used--;return 0;}return -2;
}

2、根据元素位置删除

/*** delete the array data by pos.** @param array: delete array* @param pos: the array data pos* @return -1:array is null*         -2:pos overstep the boundary of array*          0:success*/
int array_del_pos(struct dstrct_array *array, unsigned int pos)
{char *pbegin = NULL;void *pnew = NULL, *pold = NULL;int i = 0;if (array == NULL)return -1;if (pos <= 0 || pos > array->used)return -2;pbegin = array->p;for (i=pos; i<=array->used; i++){pnew = pbegin + (i - 1) * array->tpsz;pold = pbegin + i * array->tpsz;memcpy(pnew, pold, array->tpsz);}array->used--;return 0;
}

六、元素修改

/*** modify a value.** @param array: * @param pos: 1 - size* @param value: data* @return -1:array is null*         -2:pos overstep the boundary of array*          0:success*/
int  array_modify(struct dstrct_array *array, unsigned int pos, void *const value)
{char *pbegin = NULL;void *pmodify = NULL;if (array == NULL)return -1;/* adjust the pos did cross the array*/if (pos > array->size || pos <= 0)return -2;pbegin = array->p;pmodify = pbegin + (pos - 1) * array->tpsz;memcpy(pmodify, value, array->tpsz);return 0;
}

七、元素查找

/*** search the value pos.** @param array: * @param value: data* @return -1:array is null*         -2:pos overstep the boundary of array*          1 - size: the value pos*/
int array_search_pos(struct dstrct_array *array, void* const value)
{char *pbegin = NULL;void *psearch = NULL;unsigned int i = 0, pos = 0;if (array == NULL)return -1;/* adjust the pos did cross the array*/if (pos > array->size || pos <= 0)return -2;pbegin = array->p;for (i=0; i<array->used; i++){psearch = pbegin + i * array->tpsz;if (!memcmp(psearch, value, array->tpsz)){pos = i + 1;break;}}return pos;
}

八、数组清空

/*** delete the array space.** @return -1:array is null*          0:success*/
int array_empty(struct dstrct_array *array)
{if (array ==NULL)return -1;ARRAY_FREE(array->p);array->p = NULL;return 0;
}

九、数组销毁

/*** delete the array space and array control struct.* @note The array space to be empty before destroy array* @param array: delete array* @return -1:array is null*          0:success*/
int array_destroy(struct dstrct_array *array)
{if (array_empty(array) != 0)return -1;ARRAY_FREE(array);array = NULL;return 0;
}

十、验证程序

struct array_struct_test
{int a;int b;
}array_struct_test[10];int array_test[10] = {0};
void algo_array_test(void)
{struct dstrct_array *array_int = NULL;struct dstrct_array *array_str = NULL;unsigned int i = 0;unsigned int insert_value = 0x55, del_value = 0x55, mdy_value = 0x66;struct array_struct_test struct_test;/* int type test*/array_int = array_creat(10, sizeof(int));// int p[10]for (i=0;i<5;i++){array_insert(array_int, i+1, (void*)&i);        }for (i=0;i<5;i++){array_insert(array_int, 1, (void*)&insert_value);}for (i=0;i<array_int->used;i++){array_test[i] = ((int*)array_int->p)[i];//1、((int*)array->p) 2、p[i]}array_del_value(array_int, (void*)&del_value);array_del_pos(array_int,2);array_del_pos(array_int,5);array_del_pos(array_int,6);array_modify(array_int, 5, (void*)&mdy_value);memset(array_test, 0, sizeof(array_test));for (i=0;i<array_int->used;i++){array_test[i] = ((int*)array_int->p)[i];//1、((int*)array->p) 2、p[i]}/* srtruct type test*/array_str = array_creat(10, sizeof(struct array_struct_test)); // struct array_struct_test p[10]);for (i=0;i<5;i++){struct_test.a = i;struct_test.b = i + 1;array_insert(array_str, i+1, (void*)&struct_test);        }for (i=0;i<5;i++){array_insert(array_str, 1, (void*)&struct_test);}for (i=0;i<array_str->used;i++){array_struct_test[i] = ((struct array_struct_test*)array_str->p)[i];//1、((struct array_struct_test*)array->p) 2、p[i]}
}

 

 

 


http://chatgpt.dhexx.cn/article/ik1ZVHss.shtml

相关文章

C语言实现 动态数组 处理任意类型数据

引言&#xff1a;动态数组在C/C、Java、Python等语言中应用广泛&#xff0c;高级语言一般通过调用类或接口等可以快捷使用&#xff0c;C语言实现动态数组需要手动构造&#xff0c;以下为实现过程。 1 结构体构造动态数组 typedef struct Array {void **p; //维护在堆区…

C语言创建动态数组

C语言创建动态数组 1.编写步骤 1. 添加所需头文件 stdlib.h 该头文件下包含的与分配存储区相关的函数如下&#xff1a; void* malloc (size_t size);//从堆中分配size字节的存储空间 void* calloc (size_t num, size_t size);//分配数组并将数组零初始化。为 num 个元素的数…

在OpenCV里实现开运算

前面学习腐蚀和膨胀算法,并且深刻地认识到它们的特性以及作用。如果由这两种组合出来的运算又有什么样的不同呢?比如一个图像先腐蚀后膨胀的操作,会有什么结果呢?因为腐蚀是把图片白色变小,膨胀又是把图片白色变大,是否会保持原图不变呢?带着这些问题来研究一下先腐蚀后…

OpenCV python 形态学 圆形开运算

处理流程 # -*- coding: utf-8 -*- # note : 形态学 开运算 圆形内核 处理 # --------------------------------import cv2 as cv import numpy as npdef opening_circle(img_bin, kernel_size10):# 形态学kernel np.zeros((kernel_size, kernel_size), np.uint8)center_…

腐蚀、膨胀、开运算、闭运算

一、腐蚀、膨胀、开运算、闭运算 腐蚀&#xff1a;图像中的高亮部分进行膨胀 膨胀&#xff1a;原图中的高亮部分被腐蚀&#xff0c;类似于领域被蚕食 开运算&#xff1a;先腐蚀再膨胀&#xff0c;可以去掉目标外孤立的点 闭运算&#xff1a;先膨胀再腐蚀&#xff0c;可以去掉目…

【youcans 的 OpenCV 例程200篇】137. 灰度开运算和灰度闭运算原理

欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列&#xff0c;持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列&#xff0c;持续更新中 【youcans 的 OpenCV 例程200篇】137. 灰度开运算和灰度闭运算 5. 灰度级形态学 灰度级形态学将形态学操作从二值图像扩展到灰度图…

开闭运算

开运算和闭运算是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的&#xff0c;即先开后闭并不能得到原来的图像。 开运算 开运算是先腐蚀后膨胀&#xff0c;其作用是&#xff1a;分离物体&#xff0c;消除小区域。特点&#xff1a;消除噪点&#xff0c;去除小的干扰…

图像的形态学开操作(开运算)和闭操作(闭运算)的概念和作用,并用OpenCV的函数morphologyEx()实现对图像的开闭操作

大家看这篇博文前可以先看一看下面这篇博文&#xff0c;下面这篇博文是这篇博文的基础&#xff1a; 详解图像形态学操作之图形的腐蚀和膨胀的概念和运算过程,并利用OpenCV的函数erode()和函数dilate()对图像进行腐蚀和膨胀操作 图像形态学腐蚀可以将细小的噪声区域去除&#x…

OpenCV-Python图像运算变换处理:开运算和闭运算以及不同核矩阵的影响分析

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一、引言 在《OpenCV-Python图像处理&#xff1a;腐蚀和膨胀原理及erode、dilate函数介绍 https://blog.csdn.net/LaoYuanPython/article/details/109441709》等系列博文中老猿详细介绍了腐蚀和膨胀的原理、…

灰度级形态学 - 灰度开运算和灰度闭运算

目录 1. 介绍 2. code 1. 介绍 灰度级的开运算和闭运算和二值图像的处理一样&#xff0c;只不过一个作用于灰度图&#xff0c;一个作用于二值图像 灰度级的开运算公式为&#xff1a; 先对图像做腐蚀&#xff0c;然后对腐蚀的结果做膨胀运算 灰度级的闭运算公式为&#xff…

OpenCV(七)形态学操作2--开运算与闭运算

目录 概述&#xff1a; morphologyEX()函数 一、开运算&#xff08;分开&#xff09; 1、基础理论 1、作用&#xff1a; 2、代码 3、效果 二、闭运算&#xff08;封闭&#xff09; 1、基础理论 1、作用 2、过程 2、代码 3、效果 总代码 参考资料&#xff1a; 概述…

开运算—闭运算

转载&#xff1a;https://blog.csdn.net/hanshanbuleng/article/details/80657148 如果不了解腐蚀与膨胀原理的同学那请看我前一期博客哦&#xff01;&#xff09; 1.开运算 开运算 先腐蚀运算&#xff0c;再膨胀运算&#xff08;看上去把细微连在一起的两块目标分开了&…

Halcon形态学处理-腐蚀、膨胀、开运算、闭运算、顶帽运算和底帽运算

提示&#xff1a;文章参考了网络上其他作者的文章&#xff0c;以及相关书籍&#xff0c;如有侵权&#xff0c;请联系作者。 文章目录 前言一、腐蚀和膨胀1.腐蚀2.膨胀 二、开运算和闭运算1.开运算2.闭运算 三、顶帽运算和底帽运算1.顶帽运算2.底帽运算 总结参考文献 前言 图像的…

Opencv中的开运算和闭运算操作讲解(python实现)

文章目录 1.首先了解腐蚀和膨胀原理2.开运算&#xff08;1&#xff09;为什么开运算可以去白噪点呢&#xff1f;&#xff08;2&#xff09;.函数讲解&#xff08;3&#xff09;代码实战 3.闭运算&#xff08;1&#xff09;函数讲解&#xff08;2&#xff09;代码实战 1.首先了解…

膨胀 腐蚀 开运算 闭运算 matlab,11. 形态学膨胀、腐蚀、开运算、闭运算

1. 膨胀:对边界点进行扩充,填充空洞,使边界向外部扩张的过程。 2. 腐蚀:消除物体边界点,使边界向内部收缩的过程,把小于结构元素的物体去除掉。 3. 开运算: 先腐蚀后膨胀的过程称为开运算,作用:去除孤立的小点,毛刺,消除小物体,平滑较大物体边界,同时不改变其面积。 4. 闭…

开运算、闭运算及其所用

1.开运算 开运算 先腐蚀运算&#xff0c;再膨胀运算&#xff08;看上去把细微连在一起的两块目标分开了&#xff09; 开运算的效果图如下图所示&#xff1a; 开运算总结&#xff1a; &#xff08;&#xff11;&#xff09;开运算能够除去孤立的小点&#xff0c;毛刺和小桥&…

python --opencv图像处理形态学(开运算、闭运算、梯度运算、顶帽运算、黑帽运算)

引言 前面介绍了图像形态学的两种基础算法&#xff0c;图像腐蚀和图像膨胀&#xff0c;本篇接着介绍图像形态学中的开运算、闭运算以及梯度运算。 需要了解清楚图像的腐蚀与膨胀基础原理,不然真的没办法理解开运算和闭运算。 第一件事情还是给图像增加噪声&#xff0c;思路沿…

二值图像开闭运算matlab,【数字图像处理】图像开运算与闭运算

图像开启与闭合 图像开运算与闭运算与膨胀和腐蚀运算有关&#xff0c;由膨胀和腐蚀两个运算的复合与集合操作(并、交、补等)组合成的所以运算构成。 开运算与闭运算依据腐蚀和膨胀的不可逆性&#xff0c;演变而来。 开运算&#xff1a;先对图像腐蚀后膨胀 闭运算&#xff1a;先…

OpenCV之开运算与闭运算

1.开运算&#xff1a;先腐蚀&#xff0c;后膨胀 开运算总结&#xff1a; &#xff08;&#xff11;&#xff09;开运算能够除去孤立的小点&#xff0c;毛刺和小桥&#xff0c;而总的位置和形状不便。 &#xff08;&#xff12;&#xff09;开运算是一个基于几何运算的滤波器。…

halcon 开运算与闭运算

例一&#xff1a;毛刺在往外凸的面上 策略1&#xff1a;分割出黑色部分&#xff0c;然后通过开运算去掉毛刺&#xff0c;再通过原黑色部分区域减去开运算之后的区域&#xff0c;得到毛刺部分的区域。 1 read_image (Tu, C:/Users/xiahui/Desktop/tu.jpg) 2 binary_threshold …