您的位置:首页 > 其它

动态数组的实现 及 迭代器

2015-12-10 21:13 316 查看
今晚把之前的动态数组敲了一遍,感觉还是有点生疏啊,都忘记的差不多了,开辟一个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!\n");
        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:\n");
    foreach(iter, array){
        print_int(iter.ptr);
    }
    printf("\n");

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

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


还要在写写关于迭代器的操作,下次吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: