动态数组的实现 及 迭代器
今晚把之前的动态数组敲了一遍,感觉还是有点生疏啊,都忘记的差不多了,开辟一个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) ; //查找指定元素的下标
#endifdynamic_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;
}还要在写写关于迭代器的操作,下次吧。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: YII 显示代码执行时间
- 下一篇: Thinkphp 函数G 获取运行脚本内存和运行时间
