入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

动态数组的实现 及 迭代器

创建时间:2015-12-10 投稿人: 浏览次数:153

            今晚把之前的动态数组敲了一遍,感觉还是有点生疏啊,都忘记的差不多了,开辟一个void **data的动态数组,里面存的是void *,这样也实现了通用性,然后呢里面用到了函数指针,写了接口,用户可以自己写,比如void (*free)(void *ptr),还有迭代器,可以遍历任何东西,今晚先用迭代器遍历这个动态数组,为了方便,我全部用存成整数,简单方便。

       其实,这个里面呢,还有一个好的小技巧,如何按照一定数进行扩容,比如,我给31,10,15你要给我变为32,而我给我33,56你要给我变为64,也就是变为32的整数倍。

#define MODE_SIZE  32
    
static int  adjust_size(int size)
{
    size += (MODE_SIZE - 1);
    size /= MODE_SIZE;
    size *= MODE_SIZE;

    return size;
}

  还有static我也说过,定义的函数只是为了在本文件使用。迭代器里面也要学会#define宏定义定义函数。

dynamic_array.h的声明


#ifndef _ARRAY_H_
#define _ARRAY_H_

//防止头文件出现重复的包含

#include "iterator.h"

#define TRUE        (1)
#define FALSE       (0) 
#define MODE_SIZE   (32)
#define ZERO        (0)


typedef unsigned char Boolean;   
typedef struct Array Array;

//定义动态数组的结构体
struct Array{
   void **data ;    // 1.存储实体
   int capacity;    // 2.动态数组的申请大小
   int count   ;    // 3.当前元素个数
   
   //4.拷贝函数指针
   void *(*copy)(void *src_value);
   //5.匹配函数指针
   Boolean (*match)(void *value1, void *value2);
   //6.释放函数指针
   void (*free)(void *ptr);

   //7.头部插入
   Boolean (*push_front)(Array *array, void *value);
   //8.尾部插入
   Boolean (*push_back)(Array *array, void *value);
   //9.头部删除
   Boolean (*pop_front)(Array *array);
   //10.尾部删除
   Boolean (*pop_back)(Array *array);

   //迭代器操作
   //11.指向数组头部的位置
   void *(*iter_head)(Iterator *iter, Array *array);
   //12.指向数组尾部的位置
   void *(*iter_tail)(Iterator *iter, Array *array);
   //13.指向后一个元素的位置
   void *(*iter_next)(Iterator *iter, Array *array);
   //14.指向前一个元素的位置
   void *(*iter_prev)(Iterator *iter, Array *array);
};

//动态数组操作接口
Array   *init_array(int init_size)  ;    //动态数组的初始化
void    destroy_array(Array **array);    //动态数组的销毁
void    array_clean(Array *array)   ;    //动态数组清空
//插入到指定下标的前边
Boolean array_prev_insert(Array *array,
            int index, void *value);
//插入到指定下标的后边
Boolean array_next_insert(Array *array,
            int index, void *value);
int     get_array_count(Array *array)              ;    //得到动态数组的个数
void    *get_array_index(Array *array, int index)  ;    //得到指定下标的元素
Boolean delete_index_value(Array *array, int index);    //删除指定下标元素
Boolean delete_range_value(Array *array, 
                           int begin, int end)     ;    //删除指定下标范围的元素
int     find_value(Array *array, void *value)      ;   //查找指定元素的下标


#endif

dynamic_array.h的实现

#include "dynamic_array.h"
#include "tools.h"

static Boolean array_push_front(Array *array, void *value);
static Boolean array_push_back(Array *array, void *value);
static Boolean array_pop_front(Array *array);
static Boolean array_pop_back(Array *array);

static void *array_iter_head(Iterator *iter, Array *array);
static void *array_iter_tail(Iterator *iter, Array *array);
static void *array_iter_next(Iterator *iter, Array *array);
static void *array_iter_prev(Iterator *iter, Array *array);

static void array_grow(Array *array, int size);
static int  adjust_size(int size);

//头插、尾插、头删、尾删
static Boolean array_push_back(Array *array, void *value)
{
    if(array == NULL || value == NULL){
        return FALSE;
    }    

    //如果数组容量不够,则进行增长
    if(array->count >= array->capacity){
        array_grow(array, array->count + MODE_SIZE);
    }
 
    array->data[array->count] = value;
    array->count++;

    return TRUE; 
}

static Boolean array_push_front(Array *array, void *value)
{
    return array_prev_insert(array, 0, value);
}

static Boolean array_pop_front(Array *array)
{
    void *delete = NULL; 
    int i = 0;  // 计数器


    if(array == NULL || array->count == ZERO){
        return FALSE;
    }

    //进行删除操作
    array->count--;
    //记录下被删除元素存储的地址,防止内存泄露
    delete = array->data[0];
    if(array->free != NULL){
        array->free(delete);
    }
    //把后续的元素整体向前搬移
    for(i = 0; i < array->count; ++i){
        array->data[i] = array->data[i + 1];
    }
    array->data[i] = NULL;
}

static Boolean array_pop_back(Array *array)
{
    void *delete = NULL;

    if(array == NULL || array->count == ZERO){
        return FALSE;
    }

    array->count--;
    delete = array->data[array->count];
    if(array->free != NULL){
        array->free(delete);
    }
    array->data[array->count] = NULL;
    return TRUE;
}

//动态数组迭代器操作
static void *array_iter_head(Iterator *iter, Array *array)
{
    if(iter == NULL || array == NULL){
        return NULL;
    }

    iter->index = 0;
    iter->size = array->count;
    if(array->data == NULL || array->count == ZERO){
        iter->ptr = NULL;
    }else{
        iter->ptr = array->data[0];
    }
    return iter->ptr;
}

static void *array_iter_tail(Iterator *iter, Array *array)
{
    if(iter == NULL || array == NULL){  
        return NULL;
    }

    iter->index = array->count - 1;
    iter->size = array->count;

    if(array->data == NULL || array->count == ZERO){
        iter->ptr = NULL;
    }else{ 
        iter->ptr = array->data[iter->index];
    }
    return iter->ptr;
}

static void *array_iter_next(Iterator *iter, Array *array)
{
    iter->index++;
    if(iter->index >= iter->size){   //容器已经遍历完成
        iter->ptr = NULL;
    }else{
        iter->ptr = array->data[iter->index];
    }
    return iter->ptr;
}

static void *array_iter_prev(Iterator *iter, Array *array)
{
    iter->index--;
    if(iter->index < 0){
        iter->ptr = NULL;
    }else{
        iter->ptr = array->data[iter->index];
    }
    return iter->ptr;
}

//调整大小
static int  adjust_size(int size)
{
    size += (MODE_SIZE - 1);
    size /= MODE_SIZE;
    size *= MODE_SIZE;

    return size;
}

//动态数组增长的操作
static void array_grow(Array *array, int size)
{
    int adjust = 0;

    //判断size和capacity的大小关系
    if(array->capacity < size){
        //对申请的大小进行调整(向上取整)
        adjust = adjust_size(size);
        array->capacity = adjust;
        if(array->data != NULL){    //动态数组扩展
            array->data = Realloc(array->data, 
                              sizeof(void *) * adjust);
        }else{    //动态数组初始化
            array->data = Malloc(sizeof(void *) * adjust);
        }
    }    
}

//动态数组操作接口
Array   *init_array(int init_size)    //动态数组的初始化
{
    Array *array = (Array *)Malloc(sizeof(Array));
    
    //对控制信息成员进行初始化
    array->count = 0;
    
    //数组元素拷贝、比较、释放指针初始化为NULL
    array->free = NULL;
    array->match = NULL;
    array->copy = NULL;

    //头插、尾插、头删、尾删
    array->push_front = array_push_front;
    array->push_back = array_push_back;
    array->pop_front = array_pop_front;
    array->pop_back = array_pop_back;

    //迭代器操作
    array->iter_head = array_iter_head;
    array->iter_tail = array_iter_tail;
    array->iter_next = array_iter_next;
    array->iter_prev = array_iter_prev;

    array->data = NULL;
    array->capacity = 0;
    //对申请元素个数做判断
    if(init_size > 0){
        array_grow(array, init_size); 
    }

    return array;
}

void    destroy_array(Array **array)    //动态数组的销毁
{
   if(array == NULL || *array == NULL){
       return ;
   }

   //销毁数组元素对应的空间
   array_clean(*array);
   //释放data
   free((*array)->data);
   //释放array
   free(*array);
   *array = NULL;
}

void    array_clean(Array *array)    //动态数组清空
{
   //先清除data存储的元素及其所指向的空间,再修改count
   delete_range_value(array, 0, array->count - 1);
}

//插入到指定下标的前边
Boolean array_prev_insert(Array *array,
            int index, void *value)
{
    int i = 0;

    if(array == NULL || value == NULL
    || array->data == NULL 
    || index < 0 || index >= array->count){
        return FALSE;        
    }
    //1.首先判断容量
    if(array->count >= array->capacity){
        array_grow(array, array->capacity + MODE_SIZE);  
    }
    //2.index及以后的元素搬移(从后向前,防止被覆盖)
    for(i = array->count; i > =index; --i){
        array->data[i] = array->data[i - 1];
    }
    //3.插入到index
    array->data[i] = value;
    array->count++;
    return TRUE;
}

//插入到指定下标的后边
Boolean array_next_insert(Array *array,
            int index, void *value)
{
      int i = 0;

    if(array == NULL || value == NULL
    || array->data == NULL 
    || index < 0 || index >= array->count){
        return FALSE;        
    }
    //1.首先判断容量
    if(array->count >= array->capacity){
        array_grow(array, array->capacity + MODE_SIZE);  
    }
    //2.index及以后的元素搬移(从后向前,防止被覆盖)
    for(i = array->count; i > index; --i){
        array->data[i] = array->data[i - 1];
    }
    //3.插入到index
    array->data[i] = value;
    array->count++;
    return TRUE;

}

int     get_array_count(Array *array)    //得到动态数组的个数
{
    if(array == NULL){
        return ERROR;
    }
    return array->count;
}

void    *get_array_index(Array *array, int index)    //得到指定下标的元素
{
    if(array == NULL || array->count == ZERO
    || index < 0 || index >= array->count){
        return NULL;
    }
    return array->data[index];
}

Boolean delete_index_value(Array *array, int index)    //删除指定下标元素
{
    return delete_range_value(array, index, index);
}

Boolean delete_range_value(Array *array, 
                           int begin, int end)         //删除指定下标范围的元素
{
    int i = 0;
    int j = 0;

    if(array == NULL || array->count == ZERO
    || begin < 0 || begin > end || end >= array->count){
        return FALSE;
    }

    //先做删除操作,再处理数组元素的移动
    for(i = begin; i <= end; ++i){
        if(array->free != NULL){
            array->free(array->data[i]);
        }
        array->data[i] = NULL;
    }

    for(i = begin, j = end + 1; j < array->count; i++, j++){
        array->data[i] = array->data[j];
    }

    // 6  6
    array->count -= (end - begin + 1);
    return TRUE;
}

int     find_value(Array *array, void *value)   //查找指定元素的下标
{
    int i = 0;
    int count = array->count;

    if(array == NULL || array->count == ZERO
    || value == NULL){  
        return ERROR;
    }    
   
    if(array->match != NULL){ 
        for(i = 0; i < count; ++i){
            if(array->match(array->data[i], value)){  
                return i;
            }
        }
    }else{ 
        for(i = 0; i < count; ++i){
            if(array->data[i] == value){ 
                return i;
            }
        }
    }

    return -1; 

#if 0
    for(i = 0; i < array->count; ++i){
        if(array->match != NULL){
            if(array->match(array->data[i], value)){
                return i;
            }
        }else{
            if(array->data[i] == value){
                return i;
            }
        }
    }
#endif

}

iterator.h 迭代器


#ifndef _ITERATOR_H_
#define _ITERATOR_H_

typedef struct Iterator{
     void *ptr;    //指向容器中元素的位置
     int  index;   //迭代器在当前容器中的下标
     int  size;    //迭代器指向的容器中有效元素的个数
}Iterator;


// docker
//
// github
//
// dochub
//
// 虚拟化

/*
 * 正向迭代器
 *
 * iterator 
 *
 * container(list、array、stack、queue)
 *
 * */
#define FOREACH(iter, container) 
     for(container->iter_head(&(iter), container); 
     (iter).ptr; 
     container->iter_next(&(iter), container))

#define foreach FOREACH

/*
 * 反向迭代器
 *
 * iterator 
 *
 * container
 *
 * */
#define FOREACH_REVERSE(iter, container) 
     for(container->iter_tail(&(iter), container); 
     (iter).ptr; 
     container->iter_prev(&(iter), container))

#define foreach_reverse FOREACH_REVERSE

#endif


这次在tools文件中还多了一个relloc,只要在工具文件写进去就好

void *Realloc(void *ptr, size_t size)
{
    void *result = realloc(ptr, size);
    if(result == NULL){
        fprintf(stderr, "the memory is full!
");
        exit(1);
    }
    return result;
}

main.c测试一下呗


#include <stdio.h>
#include "dynamic_array.h"
#include "iterator.h"

void print_int(void *value);

void print_int(void *value)
{
    printf("%d ", *(int *)value);
}

int main(int argc, char **argv)
{ 
    Array *array = init_array(30);   //初始化动态数组
    Iterator iter = {0};
    int i = 0;
    int array1[] = {12, 23, 34, 45, 56, 67, 78, 89, 90};
    int length = sizeof(array1) / sizeof(array1[0]);  

    for(i = 0; i < length; ++i){
        array->push_back(array, &array1[i]);
    }   

    //正向遍历元素
    printf("show array:
");
    foreach(iter, array){
        print_int(iter.ptr);
    }
    printf("
");

    //反向遍历元素
    printf("show  reverse array:
");
    foreach_reverse(iter, array){
        print_int(iter.ptr);
    }
    printf("
");

    destroy_array(&array);    //动态数组的销毁
    return 0;
}


还要在写写关于迭代器的操作,下次吧。





声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。