可變陣列——連結串列前言

浪極發表於2020-12-04

可變陣列,即陣列所佔空間大小可變的陣列。對於剛剛學完陣列,還未涉入連結串列的小萌新(比如我)來說,在解決一些題目時,常常會遇到陣列內有效資料個數未知的情況。通常,我們會建立一個滿足題目條件的足夠大的陣列,但是這樣的做法往往會浪費許多空間。至此,可變陣列的出現就應運而生了。下面,我們可以嘗試幾個關於可變陣列的函式。

建立新陣列

typedef struct
{
    int *array;
    int size;
} array;
//建立新陣列
array a_create(int initsize)
{
    array a;
    a.size = initsize;
    a.array = (int *)malloc(sizeof(int *)*a.size);
    return a;
}

回收陣列空間

//回收陣列空間
void a_free(array *a)
{
    free(a->array);
    a->size =0;
    a->array = NULL;
}

檢視陣列大小

//檢視陣列大小
int a_size(const array *a)
{
    return a->size;
}

陣列增長

//陣列增長
void a_inflate(array *a,int moresize)
{
    int *p = (int *)malloc(sizeof(int)*(a->size + moresize));
    for(int i=0; i < a->size; i++)
    {
        p[i] = a->array[i];
    }
    free(a->array);
    a->array = p;
    a->size += moresize;
}

訪問陣列中某個單元

//訪問陣列中某個單元
int *a_at(array *a, int index)
{
    if(index >= a->size)
    {
        a_inflate(a, ((index/blocksize+1)*blocksize - a->size));
    }
    return &(a->array[index]);
}

測試一下上述功能

#include <stdio.h>
#include <stdlib.h>

#define blocksize 20

typedef struct
{
    int *array;
    int size;
} array;
//建立新陣列
array a_create(int initsize)
{
    array a;
    a.size = initsize;
    a.array = (int *)malloc(sizeof(int *)*a.size);
    return a;
}
//回收陣列空間
void a_free(array *a)
{
    free(a->array);
    a->size =0;
    a->array = NULL;
}
//檢視陣列大小
int a_size(const array *a)
{
    return a->size;
}
//陣列增長
void a_inflate(array *a,int moresize)
{
    int *p = (int *)malloc(sizeof(int)*(a->size + moresize));
    for(int i=0; i < a->size; i++)
    {
        p[i] = a->array[i];
    }
    free(a->array);
    a->array = p;
    a->size += moresize;
}
//訪問陣列中某個單元
int *a_at(array *a, int index)
{
    if(index >= a->size)
    {
        a_inflate(a, ((index/blocksize+1)*blocksize - a->size));
    }
    return &(a->array[index]);
}

int main(int argc, char const *argv[])
{
    array a = a_create(100);
    printf("%d\n",a_size(&a));
    *a_at(&a,0) = 10;
    printf("%d\n",*a_at(&a,0));
    int number;
    int cnt = 0;
    while(1)
    {
        scanf("%d", &number);
        if(number==-1) break;
        *a_at(&a,cnt++) = number;
    }
    for(int i=0;i<cnt;i++)
    {
        printf("%d ",*a_at(&a,i));
    }
    a_free(&a);
    return 0;
}

執行一下,我們在終端中得到了陣列大小100,陣列0號位元素為10
在這裡插入圖片描述
再輸入1 2 3 4 5 6 7 8 9 -1,終端中輸出了陣列中各個元素
在這裡插入圖片描述
至此,可變陣列的基本框架建立完畢了。
可變陣列看似完美,但有一個缺陷:它需要整塊的記憶體空間,以首地址的指標來訪問每個單元。當沒有整塊記憶體的時候(或者說可用記憶體支離破碎),我們應該怎麼辦呢?
我們可以尋找一些可用記憶體,其記憶體大小能放下單個陣列單元,再將這些陣列單元的地址像鏈條一樣關聯起來,滿足知道其中一個單元的地址即可找到所有單元的地址,並進行訪問。
當我們要處理的元素不限於數字,而是一些資料,我們就可以通過這種方式把這些資料關聯起來。這樣的資料儲存結構,就叫做連結串列。

相關文章