• 数据结构与算法9 — 二维动态字节数组


    尊重作者劳动成果,转载请注明出处,谢谢!

    1. byteArray.h

    #ifndef bytesArray_H
    #define bytesArray_H
    
    #include "types.h"
    
    //字节数组集合
    typedef struct
    {
        byte **dataSet;  //指针数组,存放着每个数组的首地址
        size_t *sizeSet; //每个数组的大小集合
        size_t capacity; //数组容量
        size_t size;     //数组长度
    } BytesArray;
    
    #define bytesArrayItem(array, index) 
        ((array)->dataSet[index])
    
    #define bytesArrayItemSize(array, index) 
        ((array)->sizeSet[index])
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
        BytesArray *bytesArray_create(size_t capacity);
        boolean bytesArray_init(BytesArray *array, size_t capacity);
        void bytesArray_destory(BytesArray *array);
        void bytesArray_free(BytesArray *array);
        void bytesArray_clear(BytesArray *array);
        boolean bytesArray_expand(BytesArray *array, size_t increment);
        boolean bytesArray_shrink(BytesArray *array);
        size_t bytesArray_length(const BytesArray *array);
        boolean bytesArray_full(const BytesArray *array);
        size_t bytesArray_get(const BytesArray *array, size_t index, byte **data);
        void bytesArray_set(BytesArray *array, size_t index, const byte *data, size_t dataSize);
        void bytesArray_add(BytesArray *array, const byte *data, size_t dataSize);
        void bytesArray_insert(BytesArray *array, size_t index, const byte *data, size_t dataSize);
        void bytesArray_remove(BytesArray *array, size_t index);
    #ifdef __cplusplus
    }
    #endif
    
    #endif

    2. byteArray.c

    #include "bytesArray.h"
    #include <string.h>
    #include <stdlib.h>
    
    static boolean byteArray_init(byte **array, const byte *data, size_t dataSize)
    {
        if (array == NULL || dataSize <= 0)
            return False;
    
        *array = (byte *)malloc(dataSize * sizeof(byte));
        if (*array == NULL)
            return False;
    
        memcpy(*array, data, dataSize);
        return True;
    }
    
    //创建并初始化一个数组(推荐使用)
    BytesArray *bytesArray_create(size_t capacity)
    {
        BytesArray *array = (BytesArray *)malloc(sizeof(BytesArray));
        if (array == NULL)
            return NULL;
    
        if (!bytesArray_init(array, capacity))
        {
            free(array);
            return NULL;
        }
    
        return array;
    }
    
    //初始化
    boolean bytesArray_init(BytesArray *array, size_t capacity)
    {
        if (array == NULL || capacity <= 0)
            return False;
    
        array->dataSet = (byte **)malloc(capacity * sizeof(byte *));
        if (array->dataSet == NULL)
            return False;
    
        array->sizeSet = (size_t *)malloc(capacity * sizeof(size_t));
        if (array->sizeSet == NULL)
        {
            free(array->dataSet);
            return False;
        }
    
        memset(array->dataSet, 0, capacity * sizeof(byte *));
        memset(array->sizeSet, 0, capacity * sizeof(size_t));
        array->capacity = capacity;
        array->size = 0;
        return True;
    }
    
    //销毁(与create配对使用)
    void bytesArray_destory(BytesArray *array)
    {
        if (array == NULL)
            return;
    
        bytesArray_free(array);
        free(array);
    }
    
    //释放内存(与init配对使用)
    void bytesArray_free(BytesArray *array)
    {
        if (array == NULL)
            return;
    
        if (array->dataSet != NULL)
        {
            //释放每一个数组
            size_t i;
            for (i = 0; i < array->size; i++)
            {
                free(array->dataSet[i]);
            }
    
            free(array->dataSet);
            array->dataSet = NULL;
        }
    
        if (array->sizeSet != NULL)
        {
            free(array->sizeSet);
            array->sizeSet = NULL;
        }
    
        array->size = 0;
        array->capacity = 0;
    }
    
    //清空数组
    void bytesArray_clear(BytesArray *array)
    {
        if (array == NULL)
            return;
    
        if (array->dataSet != NULL)
        {
            //释放每一个数组
            size_t i;
            for (i = 0; i < array->size; i++)
            {
                free(array->dataSet[i]);
            }
    
            memset(array->dataSet, 0, array->capacity * sizeof(byte *));
            memset(array->sizeSet, 0, array->capacity * sizeof(size_t));
        }
    
        array->size = 0;
        bytesArray_shrink(array); //收缩数组
    }
    
    //扩充数组
    boolean bytesArray_expand(BytesArray *array, size_t increment)
    {
        if (array == NULL || increment <= 0)
            return False;
    
        byte **data = (byte **)realloc(array->dataSet, (array->capacity + increment) * sizeof(byte *));
        if (data == NULL)
            return False;
    
        size_t *size = (size_t *)realloc(array->sizeSet, (array->capacity + increment) * sizeof(size_t));
        if (size == NULL)
            return False;
    
        array->dataSet = data;
        array->sizeSet = size;
        array->capacity += increment;
        return True;
    }
    
    //收缩数组
    boolean bytesArray_shrink(BytesArray *array)
    {
        if (array == NULL)
            return False;
    
        if (bytesArray_full(array))
            return False;
    
        size_t capacity;
        if (array->size == 0)
            capacity = 1; //收缩为1
        else
            capacity = array->size; //收缩到当前大小
    
        byte **data = (byte **)realloc(array->dataSet, capacity * sizeof(byte *));
        if (data == NULL)
            return False;
    
        size_t *size = (size_t *)realloc(array->sizeSet, capacity * sizeof(size_t));
        if (size == NULL)
            return False;
    
        array->dataSet = data;
        array->sizeSet = size;
        array->capacity = capacity;
        return True;
    }
    
    //获取数组长度
    size_t bytesArray_length(const BytesArray *array)
    {
        if (array == NULL || array->dataSet == NULL)
            return 0;
    
        return array->size;
    }
    
    //判断数据是否已满
    boolean bytesArray_full(const BytesArray *array)
    {
        if (array == NULL)
            return False;
    
        return array->size == array->capacity ? True : False;
    }
    
    //获取指定索引的元素,类似数组的下标访问
    size_t bytesArray_get(const BytesArray *array, size_t index, byte **data)
    {
        if (array == NULL || index >= array->size)
            return 0;
    
        if (data != NULL)
            *data = array->dataSet[index];
    
        return array->sizeSet[index];
    }
    
    //修改指定索引位置的元素
    void bytesArray_set(BytesArray *array, size_t index, const byte *data, size_t dataSize)
    {
        if (array == NULL || index >= array->size)
            return;
    
        if (dataSize <= array->sizeSet[index])
        {
            memcpy(array->dataSet[index], data, dataSize);
        }
        else
        {
            free(array->dataSet[index]);
            byteArray_init(&array->dataSet[index], data, dataSize);
        }
    
        array->sizeSet[index] = dataSize;
    }
    
    //在数组末尾添加元素
    void bytesArray_add(BytesArray *array, const byte *data, size_t dataSize)
    {
        if (array == NULL)
            return;
    
        if (bytesArray_full(array) && !bytesArray_expand(array, array->capacity))
            return;
    
        byteArray_init(&array->dataSet[array->size], data, dataSize);
        array->sizeSet[array->size] = dataSize;
        array->size++;
    }
    
    //在指定索引的位置上插入元素
    void bytesArray_insert(BytesArray *array, size_t index, const byte *data, size_t dataSize)
    {
        if (array == NULL || index > array->size)
            return;
    
        if (bytesArray_full(array) && !bytesArray_expand(array, array->capacity))
            return;
    
        if (index == array->size) //add
        {
            byteArray_init(&array->dataSet[array->size], data, dataSize);
        }
        else //insert
        {
            byte **src = array->dataSet + index;
            byte **dest = src + 1;
            memmove(dest, src, (array->size - index) * sizeof(byte *));
            byteArray_init(&array->dataSet[index], data, dataSize);
    
            size_t *src_s = array->sizeSet + index;
            size_t *dest_s = src_s + 1;
            memmove(dest_s, src_s, (array->size - index) * sizeof(size_t));
        }
    
        array->sizeSet[index] = dataSize;
        array->size++;
    }
    
    //删除指定索引位置的元素
    void bytesArray_remove(BytesArray *array, size_t index)
    {
        if (array == NULL)
            return;
    
        if (index >= array->size)
            return;
    
        free(array->dataSet[index]);
    
        if (index != array->size - 1)
        {
            byte **src = array->dataSet + index + 1;
            byte **dest = array->dataSet + index;
            memmove(dest, src, (array->size - 1 - 1) * sizeof(byte *));
    
            size_t *src_s = array->sizeSet + index + 1;
            size_t *dest_s = array->sizeSet + index;
            memmove(dest_s, src_s, (array->size - 1 - 1) * sizeof(size_t));
        }
    
        array->size -= 1;
    }

     3. main.c

    #include "bytesArray.h"
    #include "byteConverter.h"
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void test_bytesArray()
    {
        printf("
    ########## bytesArray ##########
    ");
    
        BytesArray *array = bytesArray_create(3);
    
        byte buf1[] = {0, 1, 2, 3};
        bytesArray_add(array, buf1, sizeof(buf1));
    
        byte buf2[] = {5, 6, 7, 8, 9};
        bytesArray_insert(array, 0, buf2, sizeof(buf2));
    
        byte buf3[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
        bytesArray_add(array, buf3, sizeof(buf3));
    
        byte *buf4 = (byte *)malloc(6);
        buf4[0] = 0x20;
        buf4[1] = 0x21;
        buf4[2] = 0x22;
        buf4[3] = 0x23;
        buf4[4] = 0x24;
        buf4[5] = 0x25;
        bytesArray_insert(array, 3, buf4, 6);
        free(buf4);
    
        printf("bytesArray: size = %d
    ", array->size);
        size_t i;
        for (i = 0; i < array->size; i++)
        {
            byte *buf;
            size_t len = bytesArray_get(array, i, &buf);
            if (len > 0)
            {
                printBytes(buf, len, False);
                printf("
    ");
            }
        }
        printf("
    ");
    
        bytesArray_remove(array, 2);
        bytesArray_clear(array);
        bytesArray_add(array, buf1, sizeof(buf1));
        bytesArray_add(array, buf2, sizeof(buf2));
    
        printf("bytesArray: size = %d
    ", array->size);
        for (i = 0; i < array->size; i++)
        {
            byte *buf = bytesArrayItem(array, i);
            size_t len = bytesArrayItemSize(array, i);
            if (len > 0)
            {
                printBytes(buf, len, False);
                printf("
    ");
            }
        }
    
        bytesArray_destory(array);
    }
    
    int main(int argc, char **argv)
    {
        test_bytesArray();
        return 0;
    }
  • 相关阅读:
    swiper 内容超出纵向滚动 解决办法
    js判断 微信浏览器 或者 QQ内置浏览器
    移动端滑动 增加弹性 滑动更加顺畅
    移动端点击激活时背景色
    文字两端对齐
    移动端元素被选中时,去除背景
    CSS动画 防止动画结束后,回归原位
    centos 防火墙配置
    知识图谱研究
    jmeter 压测工具
  • 原文地址:https://www.cnblogs.com/chenyuxin/p/15243907.html
Copyright © 2020-2023  润新知