|
|
|
|
#ifndef ARRAY_INCLUDED
|
|
|
|
|
|
|
|
|
|
#include<assert.h>
|
|
|
|
|
#include<malloc.h>
|
|
|
|
|
#include<stdlib.h>
|
|
|
|
|
/*带有assert的安全分配内存*/
|
|
|
|
|
void *malloc_s(int _size){
|
|
|
|
|
assert(_size > 0);
|
|
|
|
|
void *malloc_ptr = malloc(_size);
|
|
|
|
|
assert(malloc_ptr != NULL);
|
|
|
|
|
return malloc_ptr;
|
|
|
|
|
}
|
|
|
|
|
/*字符串变量的创建与复制*/
|
|
|
|
|
char *malloc_s_strcpy(const char *const src){
|
|
|
|
|
//申请char[]时需要多分配几个位置用于存放'\0'结束符
|
|
|
|
|
char *dst = malloc_s(strlen(src)+2);
|
|
|
|
|
strcpy(dst, src);
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
/*MARCO:根据类型安全分配内存*/
|
|
|
|
|
#define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName)))
|
|
|
|
|
/*链表单元*/
|
|
|
|
|
struct Array_{
|
|
|
|
|
void *p;
|
|
|
|
|
struct Array_ *next;
|
|
|
|
|
};
|
|
|
|
|
/*通过单向链表实现的动态数组*/
|
|
|
|
|
struct Array{
|
|
|
|
|
struct Array_ *front, *back;
|
|
|
|
|
int TypeSize;
|
|
|
|
|
int size;
|
|
|
|
|
};
|
|
|
|
|
/*链表初始化*/
|
|
|
|
|
void Array_create(struct Array *a, int ts)
|
|
|
|
|
{
|
|
|
|
|
assert("Array_create" && ts > 0);
|
|
|
|
|
a->TypeSize = ts;
|
|
|
|
|
a->size = 0;
|
|
|
|
|
a->back = a->front = NULL;
|
|
|
|
|
}
|
|
|
|
|
void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){
|
|
|
|
|
if(a == back) return ;
|
|
|
|
|
Array_release_(a->next, back, rel);
|
|
|
|
|
rel(a->p);
|
|
|
|
|
free(a->p);
|
|
|
|
|
free(a);
|
|
|
|
|
}
|
|
|
|
|
/*释放动态分配的内存,需要指定释放内部动态成员的方法*/
|
|
|
|
|
void Array_release(struct Array *a, void (*rel)(void *)){
|
|
|
|
|
Array_release_(a->front, a->back, rel);
|
|
|
|
|
a->size = 0;
|
|
|
|
|
a->back = a->front = NULL;
|
|
|
|
|
}
|
|
|
|
|
/*返回指定位置的Array_*指针
|
|
|
|
|
配合PAT宏获取内部数据*/
|
|
|
|
|
struct Array_ *Array(struct Array *a, int pos){
|
|
|
|
|
assert("Array[pos]" && pos >= 0 && pos < a->size);
|
|
|
|
|
struct Array_ *node = a->front;
|
|
|
|
|
for(int i = 0; i < pos; i ++) node = node->next;
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
/*在pos前插入*/
|
|
|
|
|
void Array_insert(struct Array *a, void *p, int pos)
|
|
|
|
|
{
|
|
|
|
|
assert("Array_insert" && pos >= 0 && pos <= a->size);
|
|
|
|
|
struct Array_ *newNode, *node = a->front;
|
|
|
|
|
newNode = MALLOC_S(struct Array_);
|
|
|
|
|
newNode->p = malloc_s(a->TypeSize);
|
|
|
|
|
memcpy(newNode->p, p, a->TypeSize);
|
|
|
|
|
if(a->size == 0){
|
|
|
|
|
a->front = newNode;
|
|
|
|
|
newNode->next = a->back;
|
|
|
|
|
}else
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < pos-1; i ++) node = node->next;
|
|
|
|
|
newNode->next = node->next;
|
|
|
|
|
node->next = newNode;
|
|
|
|
|
}
|
|
|
|
|
a->size += 1;
|
|
|
|
|
}
|
|
|
|
|
/*删除pos*/
|
|
|
|
|
void Array_delete(struct Array *a, int pos){
|
|
|
|
|
assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0);
|
|
|
|
|
struct Array_ *node = a->front, *freeNode;
|
|
|
|
|
if(pos == 0){
|
|
|
|
|
freeNode = a->front;
|
|
|
|
|
a->front = a->front->next;
|
|
|
|
|
free(freeNode->p);
|
|
|
|
|
free(freeNode);
|
|
|
|
|
}else{
|
|
|
|
|
for(int i = 0; i < pos-1; i ++) node = node->next;
|
|
|
|
|
freeNode = node->next;
|
|
|
|
|
node->next = node->next->next;
|
|
|
|
|
free(freeNode->p);
|
|
|
|
|
free(freeNode);
|
|
|
|
|
}
|
|
|
|
|
a->size--;
|
|
|
|
|
}
|
|
|
|
|
/*交换内容,即p指针*/
|
|
|
|
|
void Array__swap(struct Array_ *a, struct Array_ *b){
|
|
|
|
|
void *t = b->p;
|
|
|
|
|
b->p = a->p;
|
|
|
|
|
a->p = t;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
带有reverse选项的冒泡排序,默认(reverse == 0)是升序
|
|
|
|
|
func(a,b)为排序所依据的比较函数
|
|
|
|
|
a>b:>0
|
|
|
|
|
a==b:0
|
|
|
|
|
a < b:<0
|
|
|
|
|
*/
|
|
|
|
|
void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){
|
|
|
|
|
reverse = reverse ? -1 : 1;
|
|
|
|
|
struct Array_ *sorted = a->back, *p;
|
|
|
|
|
while(a->front->next != sorted){
|
|
|
|
|
for(p = a->front; p->next != sorted; p = p->next)
|
|
|
|
|
if(reverse*func(p->p,p->next->p) > 0)
|
|
|
|
|
Array__swap(p, p->next);
|
|
|
|
|
sorted = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*指定类型 转换(void)Array.p中的内容*/
|
|
|
|
|
#define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p)
|
|
|
|
|
/*链表的遍历*/
|
|
|
|
|
#define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next)
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
#define ARRAY_INCLUDED
|