动态线性表相较于静态线性表,其优点在于可以进行内存的扩充,而不是像静态线性表一样规定大小。
1:定义
typedef struct sqlist
{
int* a;
int capacity;
int size;
}sl;
int *a来作为数组的基地址,其中size表示当前元素个数,capacity表示拥有的空间的大小。
2:初始化
void sqlistinit(sl& ps)
{
ps.a = NULL;
ps.capacity = 0;
ps.size = 0;
}
初始化可以给a分配一点点空间,也可以直接不分配,后期再开辟内存。
3:内存检查
void seqlistcheck(sl& ps)
{
if (ps.capacity == ps.size)
{
int newcapacity = ps.capacity == 0 ? 4 : ps.capacity * 2;
int* tmp = (int*)realloc(ps.a, newcapacity * sizeof(int));
if (tmp == NULL)cout << "fail!";
else
{
ps.a = tmp;
ps.capacity = newcapacity;
}
}
}
内存检查是与静态线性表区别最大的地方,静态没有这个操作,首先进行size 与capacity大小的判断,如果相等,代表目前已有的元素个数和内存空间已满,需要再开辟内存以装入更多元素。这里用到了realloc来开辟内存,其中需要转化为int*,再用新定义的int*tmp来接收,后面再将tmp赋给a。因为在初始化时并未给空间,而size 和capacity也是0,于是便需要开辟内存,便定义了newcapacity,如果capacity为0,则给予可装入4个元素的空间,如果不是0,则变为2倍。
4:尾插
void seqlistpushback(sl& ps, int x)//尾插
{
seqlistcheck(ps);
ps.a[ps.size] = x;
ps.size++;
}
尾插之前先进行一次内存检查,然后直接在最后一个的位置上插入值即可。
5:头插
void seqlistpushfront(sl& ps, int x)//头插
{
seqlistcheck(ps);
for (int i = ps.size - 1;i >= 0;i--)
{
ps.a[i + 1] = ps.a[i];
}
ps.a[0] = x;
ps.size++;
}
头插也是,先进行内存检查,然后将所有元素后移一个单位,再将元素插入第一个位置中即可。
6:尾删
void seqlistpopback(sl& ps)//尾删
{
ps.size--;
}
直接将size减1即可,毕竟后面需要用到输出函数也是根据size作为标准来输出的。
7:头删
void seqlistpopfront(sl& ps)//头删
{
for (int i = 0;i <= ps.size-1;i++)
{
ps.a[i] = ps.a[i + 1];
}
ps.size--;
}
头删就是将元素前移一个单位,正好能将开头的元素覆盖掉,也就是所谓的头删。
8:自定义位置插入
void seqlistinsert(sl& ps, int pos, int x)
{
seqlistcheck(ps);
for (int i = ps.size-1;i >= pos - 1;i--)
{
ps.a[i+1] = ps.a[i];
}
ps.a[pos - 1] = x;
ps.size++;
}
首先进行内存检查,然后根据自定义的位置,先将元素后移,再在需要的位置插入即可。
9:自定义位置删除
void seqlisterase(sl& ps, int pos)
{
for (int i = pos - 1;i <= ps.size-1;i++)
{
ps.a[i] = ps.a[i + 1];
}
ps.size--;
}
删除也就是覆盖,将其他元素前移覆盖即可。
10:销毁
void seqlistdestroy(sl& ps)
{
free(ps.a);
ps.a = NULL;
ps.capacity = 0;
ps.size = 0;
}
free掉即可,最后将值置为空。
11:查找
int seqlistfind(sl ps,int x)//查找返回第几个(i+1)
{
for (int i = 0;i <= ps.size - 1;i++)
{
if (ps.a[i] == x)
return i + 1;
}
return -1;
}
查找成功返回第几个,不成功返回-1即可。
12:修改
void seqlistmodify(sl& ps, int pos,int x)
{
if (pos >= 0 && pos <= ps.size)
ps.a[pos - 1] = x;
else cout << "error!";
}
先判断一下修改的位置是否合适,合适后直接修改即可。
13:打印输出
void seqlistprint(sl l)
{
for (int i = 0;i < l.size;i++)
cout << l.a[i] << " ";
cout << "\n";
}
遍历然后直接打印输出即可。
14:使用test函数测试上述代码
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct sqlist
{
int* a;
int capacity;
int size;
}sl;
void sqlistinit(sl& ps)
{
ps.a = NULL;
ps.capacity = 0;
ps.size = 0;
}
void seqlistcheck(sl& ps)
{
if (ps.capacity == ps.size)
{
int newcapacity = ps.capacity == 0 ? 4 : ps.capacity * 2;
int* tmp = (int*)realloc(ps.a, newcapacity * 2 * sizeof(int));
if (tmp == NULL)cout << "fail!";
else
{
ps.a = tmp;
ps.capacity = newcapacity;
}
}
}
void seqlistpushback(sl& ps, int x)//尾插
{
seqlistcheck(ps);
ps.a[ps.size] = x;
ps.size++;
}
void seqlistpushfront(sl& ps, int x)//头插
{
seqlistcheck(ps);
for (int i = ps.size - 1;i >= 0;i--)
{
ps.a[i + 1] = ps.a[i];
}
ps.a[0] = x;
ps.size++;
}
void seqlistprint(sl l)
{
for (int i = 0;i < l.size;i++)
cout << l.a[i] << " ";
cout << "\n";
}
void seqlistpopback(sl& ps)//尾删
{
ps.size--;
}
void seqlistpopfront(sl& ps)//头删
{
for (int i = 0;i <= ps.size-1;i++)
{
ps.a[i] = ps.a[i + 1];
}
ps.size--;
}
void seqlistinsert(sl& ps, int pos, int x)
{
seqlistcheck(ps);
for (int i = ps.size-1;i >= pos - 1;i--)
{
ps.a[i+1] = ps.a[i];
}
ps.a[pos - 1] = x;
ps.size++;
}
void seqlisterase(sl& ps, int pos)
{
for (int i = pos - 1;i <= ps.size-1;i++)
{
ps.a[i] = ps.a[i + 1];
}
ps.size--;
}
void seqlistdestroy(sl& ps)
{
free(ps.a);
ps.a = NULL;
ps.capacity = 0;
ps.size = 0;
}
int seqlistfind(sl ps,int x)//查找返回第几个(i+1)
{
for (int i = 0;i <= ps.size - 1;i++)
{
if (ps.a[i] == x)
return i + 1;
}
return -1;
}
void seqlistmodify(sl& ps, int pos,int x)
{
if (pos >= 0 && pos <= ps.size)
ps.a[pos - 1] = x;
else cout << "error!";
}
void test()
{
sl s1;
sqlistinit(s1);
seqlistpushfront(s1, 1);
seqlistpushfront(s1, 2);
seqlistpushfront(s1, 3);
seqlistpushfront(s1, 4);
seqlistpushfront(s1, 5);
seqlistpushfront(s1, 6);
seqlistprint(s1);
seqlistpopback(s1);
seqlistpopback(s1);
seqlistpopback(s1);
seqlistprint(s1);
seqlistpopfront(s1);
seqlistprint(s1);
seqlistinsert(s1, 2, 22);
seqlistinsert(s1, 3, 33);
seqlistprint(s1);
seqlisterase(s1, 2);
seqlistprint(s1);
seqlisterase(s1, 3);
seqlistprint(s1);
}
int main()
{
test();
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/626a42266c8a64940653c2096b0da96a.png)
最后的结果如图所示