You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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