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