动态数组原理C语言实现

     顺序存储结构:
        用一段地址连续的存储单元依次存储线性表的数据元素。
    动态数组插入方法:
        1.判断线性表、插入位置是否合法
        2.后移从最后一个元素到插入位置元素
        3.新元素插入
        4.线性表长度+1
        5.如果空间不够,申请一块更大的空间
        6.将原空间的数据拷贝到新的空间
        7.释放旧的空间
        8.把元素放入新的空间

    图解:

        
    例子:
        //int 类型的动态数组
        //动态增加内存,将存放数据放在堆上
        // 当有新元素的插入时,需要申请内存 拷贝数据  释放内存  
        // 因此为了避免频繁的内存操作,先预先申请一块较大的内存空间
        // 容量:capacity,表示目前一共可以存放多少元素
        // size:记录当前数组中具体的元素个数

头文件定义和实现

//
// Created by zmj on 2024/1/15.
//  动态数组
//
#ifndef TEST_DYNAMIC_ARRAY_H
#define TEST_DYNAMIC_ARRAY_H
#include "stdlib.h"
#include "stdio.h"
#include <string.h>

typedef struct DYNAMICARRAY{
    int* pAddr;//存放数据的地址
    int size;//当前有多少元素
    int capacity;//容量,最大容纳个数
}Dynamic_Array;
//操作函数
//初始化
Dynamic_Array* Init_Array(){
    Dynamic_Array* myArray = (Dynamic_Array*)malloc(sizeof(Dynamic_Array));
    myArray->size =0;
    myArray->capacity = 20;
    myArray->pAddr = (int*)malloc(sizeof(int)*myArray->capacity);
    return myArray;
};
//插入
void Push_Back_Array(Dynamic_Array *arr,int value){
    if(arr==NULL){
        return;
    }
    if(arr->size == arr->capacity){
        //申请一块更大的内存空间,是原来的两倍
        int* newSpace = (int*) malloc(sizeof(int)*arr->capacity*2);
        //拷贝数据到新的空间
        memcpy(newSpace,arr->pAddr,arr->capacity* sizeof(int));
        //第三步 释放旧空间
        free(arr->pAddr);
        //更新容量
        arr->capacity=arr->capacity*2;
        arr->pAddr = newSpace;
    }
    //插入新元素
    arr->pAddr[arr->size]=value;
    arr->size++;
};
//根据位置删除
void RemoveByPos_Array(Dynamic_Array* arr,int pos){
    if(arr==NULL){
        return;
    }
    if(pos<0||pos>=arr->size){
        return;
    }
    for(int i=pos;i<arr->size;i++){
        arr->pAddr[i] = arr->pAddr[i+1];
    }
    arr->size--;
};
//查找
int Find_Array(Dynamic_Array* arr,int value){
    if(arr==NULL){
        return -1;
    }
    int pos =-1;
    for(int i=0;i<arr->size;i++){
        if(arr->pAddr[i]==value){
            pos =i;
            break;
        }
    }
    return pos;
};
//根据值删除
void RemoveByValue_Array(Dynamic_Array* arr,int value){
    if(arr==NULL){
        return;
    }
    int pos = Find_Array(arr,value);
    RemoveByPos_Array(arr,pos);
};


//打印
void Print_Array(Dynamic_Array* arr){
    if(arr==NULL){
        return;
    }
    for(int i=0;i<arr->size;i++){
        printf("%d ",arr->pAddr[i]);
    }
    printf("\n");
};
//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr){
    if(arr==NULL){
        return;
    }
    if(arr->pAddr!=NULL){
        free(arr->pAddr);
    }
    free(arr);
};
//清空数组
void Clear_Array(Dynamic_Array* arr){
    if(arr==NULL){
        return;
    }
    arr->size=0;
};
//获取动态数组容量
int Capacity_Array(Dynamic_Array* arr){
    if(arr==NULL){
        return -1;
    }
    return arr->capacity;
};
//获取动态数组当前元素个数
int Size_Array(Dynamic_Array* arr){
    if(arr==NULL){
        return -1;
    }
    return arr->size;
};
//根据位置获取某个位置元素
int At_Array(Dynamic_Array* arr,int pos){
    if(arr==NULL){
        printf("error arr is null");
        return -1;
    }
    if(pos<0||pos>=arr->size){
        printf("error index out of arr size");
        return -1;
    }
    return arr->pAddr[pos];
};


#endif //TEST_DYNAMIC_ARRAY_H

测试代码

void test01(){
    Dynamic_Array *myArray = Init_Array();
    for(int i=0;i<10;i++){
        Push_Back_Array(myArray,i);
    }
    Print_Array(myArray);
    for(int i=111;i<150;i++){
        Push_Back_Array(myArray,i);
    }
    RemoveByPos_Array(myArray,0);
    RemoveByValue_Array(myArray,9);

    Print_Array(myArray);
    FreeSpace_Array(myArray);
}

int main(){
    test01();
    return 0;
}

优点:

        可以通过[ ]括号来快速访问数组元素

缺点:

        内存大小固定,内存不够,需要扩容,复制,内存操作频繁,复制操作频繁,效率低下。        

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值