使用C語言實現(xiàn)動態(tài)數(shù)組Vector
1. 動態(tài)數(shù)組原理
定義一個結(jié)構(gòu)體類型,在結(jié)構(gòu)體中用指針指向一個在堆空間開辟的一塊內(nèi)存。
2. 編寫頭文件
在頭文件里定義Vector的數(shù)據(jù)結(jié)構(gòu)和相關(guān)操作,可以通過修改 “typedef char* Element;” 來修改存儲的數(shù)據(jù)的類型;
#ifndef VECTOR_H #define VECTOR_H // 數(shù)組默認容量設(shè)置為10 #define DEFAULT_CAPACITY 10 // 數(shù)組長度低于 HIGHT_SIZE 時,每次按照原長度翻倍擴容 // 數(shù)組長度高于 HIGHT_SIZE 時,擴充原容量的1/2 #define HIGHT_SIZE 1000 // 定義存儲的數(shù)據(jù)類型 typedef char* Element; // 定義Vector的數(shù)據(jù)結(jié)構(gòu) typedef struct vector_s { Element *data; // 用于存儲數(shù)據(jù)的動態(tài)數(shù)組的指針 int size; // 數(shù)組長度 int capacity; // 容量 } Vector; // 創(chuàng)建一個空的Vector Vector* vector_create(); // 銷毀釋放Vector void vector_destroy(Vector *v); // 向動態(tài)數(shù)組的末尾新增一個元素 void vector_push_back(Vector *v, Element val); // 向數(shù)組的前面插入一個元素 void vector_push_front(Vector *v, Element val); // 將元素val添加到索引為idx的位置,idx后面的元素依次后移 void vector_insert(Vector *v, int idx, Element val); // 給Vector的動態(tài)數(shù)組擴容 static void vector_rsize(Vector *v); // 將數(shù)組的元素從指定下標位置依次向后挪動 static void move_data(Vector *v, int idx); #endif
3. 具體實現(xiàn)
1. 創(chuàng)建一個空的Vector
Vector* vector_create() { Vector *v = (Vector*)calloc(1, sizeof(Vector)); if (v == NULL) { puts("error:創(chuàng)建一個空的Vector時分配內(nèi)存失敗"); exit(-1); } // 給Vector的成員變量賦值 v->data = c1alloc(DEFAULT_CAPACITY, sizeof(Element)); if (v->data == NULL) { puts("error:創(chuàng)建一個空的Vector時分配內(nèi)存失敗"); free(v); // 因為下面一行是直接退出程序,free(v)意義不大,但最好還是寫上,養(yǎng)成習慣 exit(-1); } v->capacity = DEFAULT_CAPACITY; return v; }
2. 銷毀釋放Vector
void vector_destroy(Vector *v) { if (v == NULL) { // Vector不能是NULL return; } free(v->data); free(v); }
3. 向動態(tài)數(shù)組的末尾新增一個元素
void vector_push_back(Vector *v, Element val) { if (v == NULL) { // Vector不能是NULL return; } if (v->size == v->capacity) { // 容量不足,擴容 vector_rsize(v); } v->data[v->size] = val; v->size++; }
4. 向數(shù)組的前面插入一個元素
void vector_push_front(Vector *v, Element val) { if (v == NULL) { // Vector不能是NULL return; } if (v->size == v->capacity) { // 容量不足,擴容 vector_rsize(v); } // 從下標0向后移動并在0下標位置賦值 move_data(v, 0); v->data[0] = val; v->size++; }
5. 將元素val添加到索引為idx的位置,idx后面的元素依次后移
void vector_insert(Vector *v, int idx, Element val) { if (v == NULL || idx < 0 || idx > v->size) { // Vector不能是NULL,索引位置不能為負且不能越界 return; } if (v->size == v->capacity) { // 容量不足,擴容 vector_rsize(v); } move_data(v, idx); v->data[idx] = val; v->size++; }
6. 給Vector的動態(tài)數(shù)組擴容
tips:此函數(shù)以下幾點需要注意
- 算術(shù)運算‘+’的優(yōu)先級比位運算符‘>>’高,要用括號括起來;
- 用realloc擴容,不能用calloc和malloc來擴大容量,數(shù)據(jù)會丟失;
- 擴容的時候要注意是給Vector的data數(shù)組擴容,即v->data;
- 只有calloc會默認自動賦初值,malloc和realloc都不會默認賦初值,記得給擴容部分附上初始值;
static void vector_rsize(Vector *v) { int old_capacity = v->capacity; // tips:算術(shù)運算‘+'的優(yōu)先級比位運算符‘>>'高,要用括號括起來 int new_capacity = v->size < HIGHT_SIZE ? old_capacity << 1 : old_capacity + (old_capacity >> 1); // tips:用realloc擴容,不能用calloc和malloc,數(shù)據(jù)會丟失! // tips:擴容的是v->data,而不是v Element *temp = realloc(v->data, new_capacity * sizeof(Element)); if (temp == NULL) { puts("error:給Vector的動態(tài)數(shù)組擴容失敗"); exit(-1); } // tips:v->data擴容部分附上初值 memset(v->data + v->size, 0, (v->capacity - v->size) * sizeof(Element)); v->data = temp; v->capacity = new_capacity; }
7. 將數(shù)組的元素從指定下標 idx 位置依次向后挪動1個位置
static void move_data(Vector *v, int idx) { for (int i = v->size - 1; i >= idx; i--) { v->data[i+1] = v->data[i]; } v->data[idx] = 0; }
到此這篇關(guān)于使用C語言實現(xiàn)動態(tài)數(shù)組Vector的文章就介紹到這了,更多相關(guān)C語言動態(tài)數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++利用stl set_difference對車輛進出區(qū)域進行判定
這篇文章主要介紹了set_difference,用于求兩個集合的差集,結(jié)果集合中包含所有屬于第一個集合但不屬于第二個集合的元素,需要的朋友可以參考下2017-03-03用c語言實現(xiàn)2000內(nèi)既能被3整除又能被7整除的個數(shù)
本篇文章是對使用c語言實現(xiàn)2000內(nèi)既能被3整除又能被7整除的個數(shù),用實例進行了分析說明,需要的朋友參考下2013-05-05