刚刚写了个静态分配内存的顺序表,再写个动态分配内存的顺序表对比
前一篇文章,静态分配内存的顺序表
顺序表有两种。一种为静态分配内存,另一种为动态分配内存。本文提供了一种动态分配内存的顺序表的简单实现。参考了数据结构(严蔚敏C语言版)教材。代码仅供参考,学习,
运行环境是Visual Studio 2019
有些判断输入是否合法的说明就跳过了,代码中可能没有体现,读者可以自行补充,
建立是cpp文件,用c文件也可以,只是需要改变一下读写数据的操作。
#include
#include
#include
#include
using namespace std;
预先定义一些内容,方便后续操作
这里追求方便,定义了ElemType为int类型,读者可以自己更改为其他类型
其中INITSIZE是初始的顺序表大小
LISTINCREMENT 是每次新增加的大小
#define OK 1 //返回OK,代表操作成功
#define ERROR 0 //返回ERROR,代表操作失败
#define INITSIZE 10
#define LISTINCREMENT 5
typedef int ElemType; //之后出现的ElemType为int类型,本代码默认数据类型是int
使用结构体定义了存储结构
struct SqList
{
ElemType* data; //定义存储空间的基地址
int length; //定义顺序表当前长度
int listsize; //定义顺序表的最大存储容量
};
初始化需要动态分配内存,使用的c语言的malloc函数,注意malloc的返回值需要强制类型转换。
int InitList(SqList& L)
{
L.data = (ElemType*)malloc(INITSIZE * sizeof(ElemType));
if (!L.data)
{
cout << "存储空间分配失败" << endl;
return ERROR;
}
L.length = 0;
L.listsize = INITSIZE;
cout << "顺序表已经构建成功" << endl;
return OK;
}
线性表创建时用到了realloc函数,用于重新分配内存空间
realloc()函数:重新分配空间
参数:原空间基址,现需空间大小
返回值:1. 成功:新空间地址(本质上是一个数值) 2. 失败:NULL
当我们在输入线性表元素个数大于构造空线性表给线性表分配初始容量时,要一直开辟新空间,直到开辟的空间大于需要的空间为止。
int CreateList(SqList& L)
{
cout << "请输入顺序表中元素的个数" << endl;
cin >> L.length;
while (L.length>L.listsize)
{
L.data = (ElemType*)realloc(L.data, (L.length + LISTINCREMENT) * sizeof(ElemType));
L.listsize = L.length + LISTINCREMENT;
}
cout << "请输入顺序表中的数据元素,以空格分隔" << endl;
for (int i = 0; i < L.length; i++)
{
cin >> L.data[i];
}
return OK;
}
很简单,不多做说明
int TraverseList(SqList L)
{
if (L.length == 0)
{
cout << "顺序表是空表" << endl;
return ERROR;
}
else
{
cout << "该顺序表中的数据元素如下" << endl;
for (int i = 0; i < L.length; i++)
{
if (i == 0)
{
cout << L.data[i];
}
else
{
cout << " " << L.data[i];
}
}
cout << endl;
return OK;
}
}
利用free()函数释放内存空间
并且将L.data指向NULL防止出现野指针
int DistoryList(SqList& L)
{
if (!L.data)
{
cout << "未建立线性表" << endl;
return ERROR;
}
free(L.data);
L.length = 0;
L.listsize = 0;
L.data = NULL; //防止出现野指针
cout << "线性表已经销毁" << endl;
return OK;
}
很简单就不多说了
int ClearList(SqList& L)
{
if (!L.data)
{
cout << "未建立线性表" << endl;
return ERROR;
}
L.length = 0;
L.listsize = INITSIZE;
free(L.data);
L.data = (ElemType*)malloc(INITSIZE * sizeof(ElemType));
return OK;
}
也很简单
bool ListEmpty(SqList L)
{
if (L.length == 0)
{
cout << "线性表是空表" << endl;
return false;
}
else
{
cout<< "线性表不是空表" << endl;
return true;
}
}
int GetElem(SqList L, int index)
{
if (index < 1 || index > L.length)
{
cout << "请输入正确的元素位序" << endl;
return ERROR;
}
else
{
cout << "第" << index << "个位置的元素为:" << L.data[index - 1] << endl;
}
return OK;
}
int LocateElem(SqList L, ElemType e)
{
for (int i = 0; i < L.length; i++)
{
if (L.data[i] == e)
{
cout << "该元素是该顺序表中的第" << i + 1 << "个元素" << endl;
return OK;
}
}
return ERROR;
}
注意插入元素后是否会导致超出内存,要判断是否需要进一步动态分布新的内存空间。
其余操作和静态分配类似
int ListInsert(SqList& L, int i, ElemType e)
{
if (i < 1 || i > L.length + 1)
{
cout << "插入位置不合法" << endl;
return ERROR;
}
if (L.length + 1 > L.listsize)
{
L.data = (ElemType*)realloc(L.data, (L.length + LISTINCREMENT) * sizeof(ElemType));
L.listsize = L.length + LISTINCREMENT;
}
for (int j = L.length; j >= i; j--)
{
L.data[j] = L.data[j - 1];
}
L.data[i - 1] = e;
L.length++;
return OK;
}
操作和静态分配类似
int ListDelete(SqList& L, int i)
{
if (i<1 || i>L.length)
{
cout << "删除位置不合法" << endl;
return ERROR;
}
cout << "删除的元素为" << L.data[i - 1] << endl;
for (int j = i; j < L.length; j++)
{
L.data[j - 1] = L.data[j];
}
L.length--;
return OK;
}
测试用的
int main()
{
SqList L;
InitList(L);
CreateList(L);
TraverseList(L);
ListInsert(L,1,2);
TraverseList(L);
ListDelete(L, 2);
TraverseList(L);
return 0;
}
主要是需要注意如何动态分配内存,这里使用了realloc()函数。
整体而言和静态分配内存的顺序表类似