動態數組:
- 內存區域連續,即每個元素的內存地址連續。
- 可用索引查看元素,數組[索引號]。
- 指定位置刪除元素,該位置之后的元素全部往前移動一位。
- 指定位置添加元素,從最后到該位置的元素全部往后移動一位。
- 物理大小:創建數組時,指定的容量大小。邏輯大小:實際已使用的容量大小。
- 擴容:數組滿時,擴大數組的內存空間。(方法:開辟新的內存空間,將原數組內容復制到新的內存區域。)
- 縮容:數組使用容量遠小于數組物理大小時,縮小數組的內存空間。(方法:開辟新的內存空間,將原數組內容復制到新的內存區域。)
C語言實現:
創建結構體數據類型:
typedef struct Array
{int *p; // 數組地址,即連續內存地址的首地址int length; // 數組物理大小,即最大容納多少元素int n; // 數組邏輯大小,即實際存儲多少元素
}Array; // 別名
創建數組變量:?
Array array;
初始化數組:
void init(Array *arr, int len)
{arr->p = (int *)malloc(len * sizeof(int)); // 分配數組內存空間if(arr->p == NULL){perror("Memory allocation failed");exit(-1);}arr->length = len; // 指定數組物理大小arr->n = 0; // 邏輯大小初始化為0
}
擴容、縮容:
使用realloc動態分配內存空間,若分配新內存,會將內容復制到新地址。
void resize(Array *arr, int len)
{int *t = (int *)realloc(arr->p, len * sizeof(int));// for(int k = 0; k < arr->n; k++)// {// t[k] = arr->p[k];// }arr->p = t;arr->length = len;
}
添加元素:
若數組滿,擴容(本文為內存空間擴大一倍)。
// 在數組尾部添加
void append(Array *arr, int data)
{if(arr->length == arr->n) // 若數組滿,擴容一倍{int newlength = arr->length * 2; resize(arr, newlength);}arr->p[arr->n] = data;arr->n++; // 每添加一個元素,邏輯大小+1
}
// 在數組指定位置添加元素
void insert(Array *arr, int i, int data)
{if(arr->length == arr->n) // 數組滿,擴容一倍{int newlength = arr->length * 2;resize(arr, newlength);}if(i < 0 || i > arr->n) // 檢查索引號是否越界{perror("index out of bounds");return ;}// 從最后一個元素到指定位置元素都要往后移動一位,空出位置給新元素int k;for(k = arr->n - 1; k >= i; k--){arr->p[k+1] = arr->p[k];}arr->p[k + 1] = data;arr->n++;
}
刪除元素:
若數組實際存儲數據小于物理大小的一半,縮容(本文將內存空間縮小一半但不小于4)。
// 從數組尾部刪除元素
int pop(Array *arr)
{if(arr->n == 0) return -1;int value = arr->p[arr->n - 1];arr->n--; // 每刪除一個元素,邏輯大小-1// 若實際數據<物理大小一半,縮容,但物理大小不小于4 if(arr->n < ceil(arr->length / 2) && arr->length > 4){int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}
// 在數組指定位置刪除元素
int del(Array *arr, int i)
{if(i < 0 || i > arr->n || arr->n == 0) // 檢查索引號是否越界{perror("index out of bounds");exit(-1);}int value = arr->p[i]; // 從指定位置到最后的元素都要往前移動一位for(int k = i; k < arr->n; k++){arr->p[i] = arr->p[i+1];}arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4) // 達到條件,縮容{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}
遍歷數組元素,獲取指定位置元素:
// 遍歷數組元素
void travel(Array *arr)
{if(arr->n == 0) return ;printf("elements: ");for(int k = 0; k < arr->n; k++){printf("%d ", arr->p[k]);}printf("\n");
}
// 獲取指定位置元素
int get(Array *arr, int i)
{if(i < 0 || i > arr->n || arr->n == 0) // 檢查索引號是否越界{perror("index out of bounds");exit(-1);}return arr->p[i];
}
排序(從小到大),倒置(從最后到開頭):
// 排序(從小到大,冒泡排序,還有其他排序方法此處省略)
void sort(Array *arr)
{int x = 0;for(int k = arr->n-1; k > 0; k--){for(int i = 0; i < k; i++){if(arr->p[i] > arr->p[i+1]){int tmp = arr->p[i];arr->p[i] = arr->p[i+1];arr->p[i+1] = tmp;x = 1;}}if(x == 0) break;}
}
// 倒置(從最后到開頭)
void inverse(Array *arr)
{if(arr->n == 0) return;for(int i = 0, k = arr->n-1; i < k; i++, k--){int tmp = arr->p[i];arr->p[i] = arr->p[k];arr->p[k] = tmp;}
}
完整代碼:(array.c)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>/* structure */
typedef struct Array // array structure
{int *p; // array memory addressint length; // maximum number of arrayint n; // actual number of array
}Array;/* function prototype */
void init(Array *, int); // array initialization
void resize(Array *, int); // increase or reduce the size of the array
void append(Array *, int); // add element to the end of the array
void insert(Array *, int, int); // add element to the specify location(start with 0)
void travel(Array *); // show element one by one
int pop(Array *); // delete element from the end of the array
int del(Array *, int); // delete element from the specify location of the array
int get(Array *, int); // show element at the specify location(start with 0)
void sort(Array *); // sort array from small to large
void inverse(Array *); // sort array form end to start/* main function */
int main(void)
{Array array;init(&array, 4);printf("lenght is %d, actual is %d\n", array.length, array.n);append(&array, 2);append(&array, 9);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);insert(&array, 1, 12);insert(&array, 0, 25);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);get(&array, 2); // get element that index=2(start with 0)sort(&array); // sort from small to largetravel(&array);inverse(&array); // sort from end to starttravel(&array);append(&array, 66); // actual length > length,need increase the size of the arrayprintf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);del(&array, 3);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);pop(&array); // actual length < length/2,need reduce the size of the arrayprintf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);pop(&array);pop(&array);pop(&array);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);return 0;
}/* subfunction */
void init(Array *arr, int len) // array initialization
{arr->p = (int *)malloc(len * sizeof(int));if(arr->p == NULL){perror("Memory allocation failed");exit(-1);}arr->length = len;arr->n = 0;
}void resize(Array *arr, int len) // increase or reduce the size of the array
{int *t = (int *)realloc(arr->p, len * sizeof(int));//for(int k = 0; k < arr->n; k++)//{// t[k]= arr->p[k];//}arr->p = t;arr->length = len;
}void append(Array *arr, int data) // add element to the end of the array
{if(arr->length == arr->n) // if array is full, expand the array to double size{int newlength = arr->length * 2; resize(arr, newlength);}arr->p[arr->n] = data;arr->n++;
}void insert(Array *arr, int i, int data) // add element to the specify location(start with 0)
{if(arr->length == arr->n) // if array is full, expand the array to double size{int newlength = arr->length * 2;resize(arr, newlength);}if(i < 0 || i > arr->n){perror("index out of bounds");return ;}int k;for(k = arr->n - 1; k >= i; k--) // from end to i,each element move back a place{arr->p[k+1] = arr->p[k];}arr->p[k + 1] = data; // leave an empty slot for the new elementarr->n++;
}void travel(Array *arr) // show element one by one
{if(arr->n == 0) return ;printf("elements: ");for(int k = 0; k < arr->n; k++){printf("%d ", arr->p[k]);}printf("\n");
}int pop(Array *arr) // delete element from the end of the array
{if(arr->n == 0) return -1;int value = arr->p[arr->n - 1];arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4) // reduce the size of array{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}int del(Array *arr, int i) // delete element from the specify location of the array
{if(i < 0 || i > arr->n || arr->n == 0){perror("index out of bounds");exit(-1);}int value = arr->p[i]; // from i to end,each element move forward one placefor(int k = i; k < arr->n; k++){arr->p[i] = arr->p[i+1];}arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4) // reduce the size of array{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}int get(Array *arr, int i) // show element at the specify location(start with 0)
{if(i < 0 || i > arr->n || arr->n == 0){perror("index out of bounds");exit(-1);}return arr->p[i];
}void sort(Array *arr) // sort array from small to large
{int x = 0;for(int k = arr->n-1; k > 0; k--){for(int i = 0; i < k; i++){if(arr->p[i] > arr->p[i+1]){int tmp = arr->p[i];arr->p[i] = arr->p[i+1];arr->p[i+1] = tmp;x = 1;}}if(x == 0) break;}
}void inverse(Array *arr) // sort array form end to start
{if(arr->n == 0) return;for(int i = 0, k = arr->n-1; i < k; i++, k--){int tmp = arr->p[i];arr->p[i] = arr->p[k];arr->p[k] = tmp;}
}
編譯鏈接: gcc -o array array.c
執行可執行文件:?./array