两者主要区别,在于静态实现的数组是写死的,而动态数组有一个IncreaseSize(SeqList &L,int len)方法可以向其加入len长度的数组空间。
再就是动态数组的销毁就是要free()对应着malloc方法,如果使用的是
L.data = new int[InitSize];对应销毁是delete操作。
线性表的静态实现
#include <iostream>
#include <cstring>
using namespace std;
#define MaxSize 50
/*
静态分配
*/
typedef struct{
int data[MaxSize];
int length;
}SqList;
void InitList(SqList &L){//初始化线性表
memset(L.data,0,sizeof(L.data));
L.length = 0;
}
int Length(SqList L){//求表长,返回线性表的长度
return L.length;
}
int LocateElem(SqList L,int e){//按值查找
for(int i = 0;i < L.length;i++){
if(L.data[i] == e){
return i+1;//下标为i等于e时,返回位序为i+1
}
}
return -1;//查找失败的返回值
}
int GetElem(SqList L,int i){//按位查找
if(i > L.length||i < 1) return -1;//i不合法时
return L.data[i-1];//因为线性表的位序是从1开始的,而数组下标是从0开始的,故i-1
}
bool ListInsert(SqList &L,int i,int e){//插入操作,第i个位置上插入指定元素e
if(i > L.length+1||i < 1) return false;//i不合法时 合法范围在1到n+1
if(L.length >= MaxSize) return false;//证明表已经满了
for(int j = L.length;j >= i;j--){//将包含i-1号位及之后的全部后移一位
L.data[j+1] = L.data[j];
}
L.data[i-1] = e;
L.length++;
return true;//插入成功
}
bool ListDelete(SqList &L,int i,int &e){//按位删除操作
if(i > L.length||i < 1) return false;//i不合法时
e = L.data[i-1];
for(int j = i;j<L.length;j++){
L.data[j-1] = L.data[j];//元素前移
}
L.length--;
return true;//删除成功
}
void PrintList(SqList L){//打印操作
for(int i = 0;i < L.length;i++){
cout<<"下标:"<<i<<"值:"<<L.data[i]<<endl;
}
}
bool Empty(SqList L){//判空操作
if(L.length==0) return true;//证明是空的
return false;
}
int main(){
SqList L;
InitList(L);
for(int i = 1;i < 15;i++){
ListInsert(L,i,i);
}
PrintList(L);
cout<<GetElem(L,10)<<endl;
if(Empty(L)){
cout<<"线性表是空的!"<<endl;
}else{
cout<<"线性表非空!"<<endl;
}
int ans = 0;
ListDelete(L,10,ans);
cout<<ans<<endl;
PrintList(L);
return 0;
}
线性表的动态实现
#include <iostream>
using namespace std;
#define InitSize 20
/*
动态分配
*/
typedef struct{
int *data;
int length,MaxSize;
}SeqList;
void InitList(SeqList &L){//初始化操作
//malloc会返回一个分配好地址的指针
L.data = (int*)malloc(sizeof(int)*InitSize);//第一个*是指针的意思 第二个*是乘的意思
L.length = 0;
L.MaxSize = InitSize;
}
void DestroyList(SeqList &L){//销毁操作
if(L.data){
free(L.data);
L.data = NULL;//释放L.data指针本身
L.length = 0;
L.MaxSize = 0;
}
}
bool IncreaseSize(SeqList &L,int len){//动态地增长数组的长度
int *p = L.data;//记录下之前数组0号下标的位置
L.data = (int*)malloc(sizeof(int)*(L.MaxSize+len));//分配MaxSize+len的空间
if(L.data){//证明有分配到空间
for(int i = 0;i<L.length;i++){
L.data[i] = p[i];//将原先的内存空间的数组数据搬过来
}
L.MaxSize = L.MaxSize+len;
free(p);
return true; //分配成功
}
return false;//分配失败
}
int Length(SeqList L){//求表长,返回线性表的长度
return L.length;
}
int LocateElem(SeqList L,int e){//按值查找
for(int i = 0;i < L.length;i++){
if(L.data[i] == e){
return i+1;//下标为i等于e时,返回位序为i+1
}
}
return -1;//查找失败的返回值
}
int GetElem(SeqList L,int i){//按位查找
if(i > L.length||i < 1) return -1;//i不合法时
return L.data[i-1];//因为线性表的位序是从1开始的,而数组下标是从0开始的,故i-1
}
bool ListInsert(SeqList &L,int i,int e){//插入操作,第i个位置上插入指定元素e
if(i > L.length+1||i < 1) return false;//i不合法时 合法范围在1到n+1
if(L.length >= L.MaxSize) return false;//证明表已经满了
for(int j = L.length;j >= i;j--){//将包含i-1号位及之后的全部后移一位
L.data[j+1] = L.data[j];
}
L.data[i-1] = e;
L.length++;
return true;//插入成功
}
bool ListDelete(SeqList &L,int i,int &e){//按位删除操作
if(i > L.length||i < 1) return false;//i不合法时
e = L.data[i-1];
for(int j = i;j<L.length;j++){
L.data[j-1] = L.data[j];//元素前移
}
L.length--;
return true;//删除成功
}
void PrintList(SeqList L){//打印操作
for(int i = 0;i < L.length;i++){
cout<<"下标:"<<i<<"值:"<<L.data[i]<<endl;
}
}
bool Empty(SeqList L){//判空操作
if(L.length==0) return true;//证明是空的
return false;
}
int main(){
SeqList L;
InitList(L);
for(int i = 1;i < 15;i++){
ListInsert(L,i,i);
}
PrintList(L);
cout<<GetElem(L,10)<<endl;
if(Empty(L)){
cout<<"线性表是空的!"<<endl;
}else{
cout<<"线性表非空!"<<endl;
}
int ans = 0;
ListDelete(L,10,ans);
cout<<ans<<endl;
PrintList(L);
//动态添加20个空间的使用
IncreaseSize(L,20);
for(int i = 14;i < 30;i++){//因为前面删除了一个,所以要从14号位开始插入
ListInsert(L,i,i);
}
PrintList(L);
DestroyList(L);
return 0;
}
本文详细对比了线性表的静态实现与动态实现的区别,重点介绍了动态数组的IncreaseSize方法,以及如何在C++中使用malloc和free进行内存管理。通过具体代码实例,展示了静态数组和动态数组的初始化、插入、删除、查找等基本操作。

被折叠的 条评论
为什么被折叠?



