数据结构之动态顺序表

动态顺序表

动态顺序表是跟静态顺序表大体相似,有些地方是不同的,动态顺序表是在动态变化中,当我们的所需的内存不够时,它会自动开辟一个我们需要的空间,来供我们使用。

动态顺序表与静态顺序表的不同在于初始化/销毁/所有插入,其他和静态顺序表完全一样。

定义一个结构体

先将我们需要的都定义好

#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我!

猜你喜欢

转载自blog.csdn.net/skrskr66/article/details/84709912
今日推荐