动态顺序表
动态顺序表是跟静态顺序表大体相似,有些地方是不同的,动态顺序表是在动态变化中,当我们的所需的内存不够时,它会自动开辟一个我们需要的空间,来供我们使用。
动态顺序表与静态顺序表的不同在于初始化/销毁/所有插入,其他和静态顺序表完全一样。
定义一个结构体
先将我们需要的都定义好
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
//为了观看方便先写在开头,正常应该需要什么去使用什么
typedef int DataType;
#define INIT_CAPACITY(3)//定义一个动态的初始化空间容量为3
typedef struct SeqListD{
DataType* parray;
int capacity;
int size;
}
在结构体的定义中,静态与动态的定义是不同的。静态的是直接定义了一个空间是有范围确定的数组。但是动态不同,动态定义的是一个指针,在这里面存储的范围是不确定的,当我们定义了一个当前我们认为足够大的空间时,它是在一个计算机给我们的随机地址中。当我们需要更大的空间时,我们将申请新空间,这个时候我们将数据转移,先将所有数据转移到新的空间,之后我们将旧的空间释放掉。这个时候空间是新开辟的一段空间,但是我们的地址是计算机重新分配的一段新地址。
初始化
void SeqListInit(SeqListD *pSeq){
pSeq->capacity = INIT_CAPACITY;//当前容量我们都先设置为3,每当我们不够时,
//我们就调用其他函数去扩充它
pSeq->parray = (DataType *)malloc(sizeof(DataType)*pSeq->capacity);//我们的数组利用malloc函数
//类型 //4*3
assert(pSeq->parray);//判断我的指针是否正常
pSeq->size = 0;
}
malloc(): malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。
一般需和free函数配对使用。
销毁
void SeqListDestory(SeqListD *pSeq){
free(pSeq->parray);
//将它释放掉
pSeq->capacity = 0;
pSeq->size = 0;
pSeq->parry = NULL;
//所有一切还原
}
插入
void SeqListPushBack(SeqListD *pSeq,DataType data){
//静态:如果满了,不处理/报错
//动态:加入扩容机制
ExpandIfRequired(pSeq);//每次都需要去判断是否达到条件可以实现
pSeq->parray[pSeq->size] = data;//
pSeq->size++;
}
判断是否需要扩大
static void ExpandIfRequired(SeqListD *pSeq){
if(pSeq->size < pSeq->capacity){
return;//还没满
}
//扩容
pSeq->capacity *= 2;
//开辟新空间
DataType *newArray = (DataType *)malloc(sizeof(DataType)*pSeq->capacity);
assert(newArray);
//数据搬移
for(int i = 0;i < pSeq->size;i++){
newArray[i] = pSeq->parray[i];
}
//释放老空间,申请的新空间与动态顺序表关联起来
free(pSeq->parray);
pSeq->parray = newArray;
}
同理,所有插入都需要加入扩容机制
其他的操作与静态顺序表的操作是相近的。可以参考我之前的对照着看。
数据结构重新在学!如有不对,请cue我!