1. 程式人生 > 實用技巧 >C語言陣列資料結構實現

C語言陣列資料結構實現

  陣列是最基礎的資料結構,常用的陣列有一維陣列和二維陣列。您是否想過一維和二維陣列乃至更高維度的陣列是否有相同的實現方法呢?這篇部落格介紹陣列一般化的實現方式。

#include <stdio.h>  
#include <stdlib.h>
#include <stdarg.h> //使用可變引數的庫
#define MAX_ARRAY_DIM 3//陣列的最大維度限制

typedef struct{
    int *base;//陣列的開始地址無論多少維的陣列展開後都可以看作線性一維的,那麼這個線性一維陣列就有一個起始地址
    int dim;//陣列的維度數
int *bound;//陣列每一維度的邊界,比如二維陣列arr[3][4],第二維的訪問邊界為<3,第一維的訪問邊界為<4 int *constants;//陣列定址時的常量 ,比如二維陣列arr[3][4],如果想要訪問arr[2][3],2中的每個一我們需要跳過4個格子,3中的每個一我們需要跳過1個格子 //又比如三維陣列arr[5][4][3],如果想到訪問arr[x][y][z],則x中的每個一需要跳12個格子,y中的每個一需要調3個格子,z中每個一需要跳1個格子 }Array; void InitArray(Array *A, int dim, ...){//
初始化陣列 va_list ap; va_start(ap,dim); if(dim < 1 || dim > MAX_ARRAY_DIM){ return; } A->dim = dim; A->bound = (int*)malloc(dim * sizeof(int));//bound陣列的大小等於維度的個數,分別儲存各個維度的邊界 int elemTotal = 1; int i; for(i = 0; i < dim; ++i){ A->bound[i] = va_arg(ap,int
);//記錄陣列每一維度的邊界 elemTotal *= A->bound[i];//計算陣列總的元素個數 } va_end(ap); A->base = (int*)malloc(elemTotal * sizeof(int));//開闢陣列元素總量所需的空間,返回空間起始地址賦值給base A->constants = (int *)malloc(dim * sizeof(int)); A->constants[dim - 1] = 1;//預設始終為 1, arr[a1][a2]..[an],an中的每個一總是隻需要跳過一格 for(i = dim - 2; i >= 0; --i){//i是倒過來數的 A->constants[i] = A->bound[i + 1] * A->constants[i + 1];//設定定址時的常量,即需要跳過幾格 }//如果不太懂,下面有圖片解釋這個表示式的含義 } void DestoryArray(Array *A){//銷燬陣列 if(!A->base){ return; } free(A->base); if(!A->bound){ return; } free(A->bound); if(!A->constants){ return; } free(A->constants); } int Locate(Array *A,va_list ap,int *off){// 計算給定陣列下標對應的地址偏移量 *off = 0; int i; for(i =0; i < A->dim; ++i){ int index = va_arg(ap,int); if(index < 0 || index > A->bound[i]){//防止訪問的下標越界 return 0; } (*off) += A->constants[i] * index;//constants的作用在這裡得到了體現 } return 1; } void Value(Array *A, int *e, ...){//e用來接收資料 va_list ap; va_start(ap,e); int off; if(!Locate(A,ap,&off)){ return; } *e = *(A->base + off); } void Assign(Array *A, int e, ...){//給定陣列下標給其賦值 va_list ap; va_start(ap,e); int off; if(!Locate(A,ap,&off)){ return; } *(A->base + off) = e; } int main(int argc, char *argv[]) { Array *arr =(Array*) malloc(sizeof(Array)); int e; int row = 3,col = 4; InitArray(arr,2,row,col); int i,j; srand((unsigned)getpid()); for(i = 0; i < row; ++i){ for(j = 0; j < col; ++j){ e = rand()%100; Assign(arr,e,i,j); } } int tmp; for(i = 0; i < row; ++i){ for(j = 0; j < col; ++j){ Value(arr,&tmp,i,j); printf("%d\t",tmp); } printf("\n"); } DestoryArray(arr); return 0; }