数据结构---动态顺序表的几个重要函数
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
1.前言:malloc(动态分配函数)的用法
2.动态顺序表的初始化
1.动态顺序表的初始化
2.动态顺序表的销毁
4.增、删、查、换(删查换与静态表相同)
1) 动态顺序表的增加空间
2)动态顺序表的增
前言:malloc函数
1.malloc函数头文件 #include<malloc.h>
2.malloc函数原型:extern void *malloc(unsigned int num)
3.malloc函数的返回值:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL
4.malloc函数使用方法和注意事项
1>.malloc函数是动态内存分配函数,用于申请一块连续的指定大小的内存块区域,以void*类型返回分配的内存区域地址。
2>.malloc函数的使用形式
int *p = NULL;
int n=100;
p = (int*)malloc(sizeof(int)*n);
注:malloc只开辟空间,不进行类型检查,只是在使用时进行类型的强制转换,所以通用的malloc函数代码形式为: 指针自身 = (指针类型*)malloc(sizeof(int)*数据数量),要注意先计算所需开辟的字节数再进行使用 。
3>.free函数(至关重要!!!)
作用:释放malloc函数给指针变量分配的内存空间。注意!!!使用后指针变量一定要重新指向NULL,防止失效指针的出现。 如果malloc不用free函数释放分配的空间,那么这个空间将一直在内存中存在,造成内存泄漏。
下面进入正题:动态顺序表的操作
1.动态顺序表的初始化
2.动态顺序表的销毁
3.动态顺序表的申请增加空间
4.增、删、查、换
动态顺序表的初始化
顺序表的定义
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define INITSIZE 10 // 顺序表的初始长度。
#define EXTSIZE 5 // 每次扩展元素的个数。
typedef int ElemType; // 自定义顺序表的数据元素为整数。
typedef struct
{
ElemType *data; // 存储顺序表中元素的首地址。
unsigned int maxsize; // 顺序表元素的最大长度。
unsigned int length; // 顺序表中元素的个数。
}SeqList,*PSeqList;
注意:与静态表不同的是我们在此直接定义的是顺序表中的首地址,但是操作依旧可以使用数组的模式操作
//顺序表元素归零
void ClearList(PSeqList LL) //参数为指针
{
if(LL == NULL) return; //检查空指针
LL->length == 0; //归零顺序表长度
memest(LL->data, 0, sizeof(ElemType)*LL->maxize);
}
//顺序表初始化
void InitList(PSeqList LL) //参数为指针
{
LL->data = (int*)malloc(sizeof(ElemType)*INITSIZE); //之前定义的初始长度
//上面的指向本身就是一个地址,指向数据串的开头;顺序表创建成功
LL->maxsize=INITSIZE; //最大值置为向初始值
ClearList(LL); //顺序表置零
}
初始化由两段代码组成,一段是上一次我们的老朋友ClearList函数,一段就是这次的正主初始化函数InitList。其中ClearList函数负责将函数置零,InitList函数与静态顺序表不同的就是其需要先申请空间再进行定义。不要忘记将最大值调为初始值。
动态顺序表的销毁
void DestroyList(PSeqList LL)
{
free(LL->data);
LL->maxsize=0;
LL->length=0;
}
销毁的两个步骤:首先,释放之前申请的内存空间,然后将长度和最大储存空间一起置为零。(先学会安全的拆除,再去学建设。)
重点:动态顺序表的增
增由两个函数组成,一个是与静态顺序表类似的循环后移插入函数,一个是扩容函数。
扩容函数
int ExtList(PSeqList LL)
{
ElemType *newdata = (ElemType*)malloc(sizeof(ElemType)*(LL->maxsize+EXTSIZE));
//创建一个新的地址并分配一个新的内存
if (newdata == NULL) return 0;
// 如果分配失败,返回0。
memset(newdata, 0, sizeof(ElemType)*(LL->maxsize+EXTSIZE));
//新地址置为零
memcpy(newdata, LL->data, sizeof(ElemType)*LL->maxsize);
//将原地址的数据复制过来
free(LL->data);
//释放原地址的内存
LL->data = newdata;
//将指针指向调整到现在的新地址
LL->maxsize = LL->maxsize + EXTSIZE;
//最大长度加五
return 1;
}
注意:这个扩容的思路与大家想象中的扩容不一样,此处扩容的步骤是再1>.开辟一个length(长度)加上EXTSIZE的新空间,2>.和一个新指针,3>.之后将原先的数据移动过来,4>.释放原来的空间和指针。(为了减小时间复杂度,此处不用for循环,直接调用memcpy函数)
增加函数
与静态顺序表的函数相同
int InsertList(PSeqList LL, unsigned int ii, ElemType *ee)
/*参数的意义:LL是顺序表的地址,ii是要插入的位置,*ee是插入的数据
在此处用指针的形式是方便通过以此来了解插入为结构体时的形式*/
{
int tt, kk; //tt是为了调用扩容函数,kk是循环计数
if(ii<0 || ii>LL->length){
printf("插入位置不合法!");
return 0;
}
if(ii>LL->maxsize){
tt = ExtList(LL);
if(tt==0){
printf("很遗憾,插入失败,已返回。");
return 0;
}
}
for(kk=LL->length; kk>=ii; kk--){
memcpy(&LL->data[kk],&LL->data[kk-1],sizeof(ElemType));
//注意下标是从零开始的,所以是由【kk-1】移动到【kk】
}
memcpy(&LL->data[ii-1],&ee,sizeof(ElemType));
LL->length++; // 表的长度加1。
return 1;
}