C实现基本动态数组

C语言实现基本动态数组:

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 #include <string.h>
  4 #define INIT_CAP 4 //初始分配空间大小
  5 #define _Bool unsigned short
  6 typedef int ADT;
  7 typedef struct{
  8     unsigned size; //数组元素数量
  9     unsigned capacity; //容量大小
 10     ADT *begpos, *endpos; //初始位置指针,末尾位置指针
 11 }Arr, *pArr;
 12 
 13 pArr Init(pArr p){
 14     p -> begpos = (ADT*)malloc(sizeof(ADT) * INIT_CAP); //申请 每个元素字节数*初始分配存储单元个数 大小的空间
 15     p -> size = 0; //初始个数置为0
 16     p -> capacity = INIT_CAP; //初始容量为默认大小
 17     p -> endpos = p -> begpos; //初始化尾指针与首指针位置相同
 18 }
 19 
 20 _Bool Extend(pArr p){ //扩展数组容量大小
 21     ADT* newspace = (ADT*)malloc(sizeof(ADT) * p -> capacity * 2); //申请原来空间两倍大小的空间
 22     if(newspace == NULL) return 0; //申请失败返回0
 23     memcpy(newspace, p -> begpos, sizeof(ADT) * p -> capacity); //将原来数组元素复制到新数组
 24     free(p -> begpos); //释放原数组空间
 25     p -> begpos = newspace; //首指针指向新数组首部
 26     p -> capacity *= 2; //容量扩大2倍
 27     p -> endpos = p -> begpos + p -> size; //尾指针更新
 28     return 1;
 29 }
 30 
 31 ADT* Add(const pArr p, const ADT value){ //添加新元素
 32     if(p -> capacity == p -> size){ //判断空间是否已满
 33         if(!Extend(p)){ //扩展新空间
 34             printf("add %d failed! Maybe have memery not enough.\n", value);
 35             return NULL;
 36         }
 37     }
 38     *p -> endpos = value; //在尾指针处放置新元素
 39     ++ p -> endpos; //尾指针后移
 40     ++ p -> size; //元素数量增加
 41     printf("Add number: %d, Size now: %d/%d\n", value, p -> size, p->capacity);
 42 }
 43 
 44 void Clear(const pArr p){ //清空数组
 45     p -> size = 0;
 46     p -> endpos = p -> begpos;
 47 }
 48 
 49 void Desdroy(const pArr p){ //销毁数组
 50     free(p -> begpos);
 51 }
 52 
 53 void Traverse(const pArr p){ //遍历数组
 54     if(!p -> size){
 55         printf("Empty!\n");
 56         return;
 57     }
 58     printf("\nTraverse: ");
 59     ADT* beg = p -> begpos;
 60     while(beg != p -> endpos){
 61         printf("%d ", *beg);
 62         ++ beg;
 63     }
 64     printf("\n");
 65 }
 66 
 67 _Bool less(const ADT v, const ADT aim){ //条件函数(小于某值)
 68     return v < aim;
 69 }
 70 _Bool grater(const ADT v, const ADT aim){ //条件函数(大于某值)
 71     return v > aim;
 72 }
 73 
 74 unsigned Remove(const pArr p, const int aim){ //删除数组值为 aim 的元素
 75     unsigned count = 0;
 76     ADT* w = p -> begpos, *r = p -> begpos; //设置两个指针初始指向首地址
 77     for(; r!=p -> endpos; ++r){ //通过两个指针移动删除某值
 78         if(*r == aim){
 79             ++ count;
 80             -- p -> size;
 81         }
 82         else *w++ = *r;
 83     }
 84     p -> endpos = w;
 85     return count; //返回删除个数
 86 }
 87 
 88 unsigned Remove_if(const pArr p, const ADT arg, _Bool(* con)(ADT, ADT)){ //条件删除指定元素
 89     unsigned count = 0;
 90     ADT* w = p -> begpos, *r = p -> begpos;
 91     for(; r!=p -> endpos; ++r){
 92         if(con(*r, arg)){
 93             ++ count;
 94             -- p -> size;
 95         }
 96         else *w++ = *r;
 97     }
 98     p -> endpos = w;
 99     return count;
100 }
101 
102 int main(){
103     Arr array;
104     Init(&array);
105 
106     Add(&array, 3);
107     Add(&array, 6);
108     Add(&array, 2);
109     Add(&array, 1);
110     Add(&array, 5);
111     Traverse(&array);
112     Clear(&array);
113     Traverse(&array);
114 
115     Desdroy(&array);
116     Init(&array);
117     Add(&array, 4);
118     Add(&array, 4);
119     Add(&array, 3);
120     Add(&array, 8);
121     Add(&array, 4);
122     Traverse(&array);
123     printf("Has removed %d numbers.\n", Remove_if(&array, 5, less)); //删除小于5的所有元素
124     Traverse(&array);
125 
126     return 0;
127 }

 

测试输出:

Add number: 3, Size now: 1/4
Add number: 6, Size now: 2/4
Add number: 2, Size now: 3/4
Add number: 1, Size now: 4/4
Add number: 5, Size now: 5/8

Traverse: 3 6 2 1 5 
Empty!
Add number: 4, Size now: 1/4
Add number: 4, Size now: 2/4
Add number: 3, Size now: 3/4
Add number: 8, Size now: 4/4
Add number: 4, Size now: 5/8

Traverse: 4 4 3 8 4 
Has removed 4 numbers.

Traverse: 8 

 

posted @ 2018-04-07 21:56  AlphaKin  阅读(2147)  评论(0编辑  收藏  举报