动态数组的实现 及 迭代器
2015-12-10 21:13
316 查看
今晚把之前的动态数组敲了一遍,感觉还是有点生疏啊,都忘记的差不多了,开辟一个void **data的动态数组,里面存的是void *,这样也实现了通用性,然后呢里面用到了函数指针,写了接口,用户可以自己写,比如void (*free)(void *ptr),还有迭代器,可以遍历任何东西,今晚先用迭代器遍历这个动态数组,为了方便,我全部用存成整数,简单方便。
其实,这个里面呢,还有一个好的小技巧,如何按照一定数进行扩容,比如,我给31,10,15你要给我变为32,而我给我33,56你要给我变为64,也就是变为32的整数倍。
还有static我也说过,定义的函数只是为了在本文件使用。迭代器里面也要学会#define宏定义定义函数。
dynamic_array.h的声明
dynamic_array.h的实现
iterator.h 迭代器
这次在tools文件中还多了一个relloc,只要在工具文件写进去就好
main.c测试一下呗
还要在写写关于迭代器的操作,下次吧。
其实,这个里面呢,还有一个好的小技巧,如何按照一定数进行扩容,比如,我给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; }
还要在写写关于迭代器的操作,下次吧。
相关文章推荐
- ADO.NET(数据库访问技术)
- Bash环境配置文件
- 定义工具类中函数随时打开某Activity
- 如何选择正确的HTTP状态码
- Dynamics CRM2016 新功能之Solution enhancements
- Dynamics CRM2016 新功能之Solution enhancements
- Dynamics CRM2016 新功能之Solution enhancements
- Dynamics CRM2016 新功能之Solution enhancements
- 简单典型贪心---(解题报告)HDU2037---今年暑假不AC
- iOS 遇到过的bug(未完待续)
- LocalDB连接失败
- 限制内部地址NAT转换条目
- python 打开图像
- 对象池 c++11
- ZZULIOJ 1816: 矩形 【矩形重叠面积的计算(区分相离与相交)】
- 面试宝典:破解最难回答的23个问题及8大面试通关考题
- CSDN论坛积分等级制度
- 185 Which two client requests are captured during database replay Capture? (Choose two) A. Flashback
- 限制内部地址NAT转换条目
- gflags的使用