初始化最小容量为cap

每次达到cap则扩容成两倍cap

对于一个空的数组,不断的加入元素直到n个,扩容的次数应该是x次,$cap\times 2^x \ge n \Rightarrow x\approx O(log_2\frac{n}{cap})$

如果申请大小为k的内存,时间复杂度是$O(k)$的话。

第$i$次申请内存的大小是$cap\times 2^i$,申请$x\approx O(log_2\frac{n}{cap})$次,总内存大小是$cap\times(2^0+2^1+\cdots+2^x)\Rightarrow cap\times(2^{x+1}-1)\Rightarrow cap\times(2\frac{n}{cap}-1)\approx O(n)$

扩容后,原有连续的内存首地址会发生变化,所以元素内不能存元素的地址,否则扩容后元素内保留的是野指针。

// ==================== vector =======================
typedef struct cntnode {
    unsigned long long key;
    struct cntnode* prev;
    struct cntnode* next;
} cntnode;

// #define VEC_VT cntnode* 直接替换,连续声明变量失效
typedef cntnode* VEC_VT; 

typedef struct {
    VEC_VT* data;      
    int size;   
    int cap;
} vector;

vector* vc_new(int size) {
    vector* vec = (vector*)malloc(sizeof(vector));
    assert(vec != NULL);
    
    int cap = 16;
    while (size>cap) cap<<=1;
    vec->data = (VEC_VT*)malloc(cap * sizeof(VEC_VT));
    assert(vec->data != NULL);
    
    memset(vec->data, 0, size*sizeof(VEC_VT));
    vec->size = size;
    vec->cap = cap;
    return vec;
}

void vc_del(vector* v) {
    free(v->data);
    free(v);
}

void vc_reverse(vector* vec) {
    int l = 0, r = vec->size-1;
    while (l<r) {
        VEC_VT t = vec->data[l];
        vec->data[l] = vec->data[r];
        vec->data[r] = t;
        l++; r--;
    }
}

void vc_push_back(vector* vec, VEC_VT value) {
    if (vec->size >= vec->cap) {
        VEC_VT* new_data = (VEC_VT*)realloc(vec->data, 2 * vec->cap * sizeof(VEC_VT));
        // printf("before %p, after %p\\n", vec->data, new_data);
        // 地址会发生变化,所以元素内不能存元素的地址,否则扩容后会出现野指针
        assert(new_data != NULL);
        vec->data = new_data;
        vec->cap <<= 1;
    }
    vec->data[vec->size] = value;
    vec->size++;
}

void vc_pop_back(vector* vec) {
    assert(vec->size>0);
    vec->size--;
}

VEC_VT vc_get(vector* vec, size_t index) {
    assert(vec && index<vec->size);
    return vec->data[index];
}

void vc_set(vector* vec, int index, VEC_VT value) {
    assert(vec && index<vec->size);
    vec->data[index] = value;
}

void vc_swap(VEC_VT* a, VEC_VT* b) {
    VEC_VT t = *a;
    *a = *b;
    *b = t;
}

typedef int (*VCmp)(VEC_VT, VEC_VT);

// modify
int vc_cmp(VEC_VT a, VEC_VT b) {
    // return a-b;
    return -1;
}

void vc_sort(vector* nums, int left, int right, VCmp cmp) { // [left, right)
    if (left + 1 >= right) return ;
    int m = left+right>>1;
    vc_sort(nums, left, m, cmp);
    vc_sort(nums, m, right, cmp);
    vector* mg = vc_new(0);
    int p1 = left, p2 = m;
    while (p1<m && p2<right) {
        if (cmp(nums->data[p1], nums->data[p2])<0) { // cmp(a, b)<0 a<b
            vc_push_back(mg, nums->data[p1++]);
        } else {
            vc_push_back(mg, nums->data[p2++]);
        }
    }
    while (p1<m) {
        vc_push_back(mg, nums->data[p1++]);
    }
    while (p2<right) {
        vc_push_back(mg, nums->data[p2++]);
    }
    for (int i=left; i<right; i++) {
        nums->data[i] = mg->data[i-left];
    }
    vc_del(mg);
}

// modify
void vc_print(vector* vec) {
    // your code
    printf("vector size:%d, cap:%d\\n", vec->size, vec->cap);
    for (int i=0; i<vec->size; i++) {
        VEC_VT ed = vec->data[i], cur = ed->next;
        printf("idx:%d addr:%p pre:%llu nxt:%llu \\nlru order:", i, ed, GET_PREV(ed->key), GET_NEXT(ed->key));
        while (ed != cur) {
            printf(" %llu", cur->key);
            cur = cur->next;
        }
        printf("\\n");
    }
}