ToB企服应用市场:ToB评测及商务社交产业平台
标题:
数据布局 之 【顺序表实现】(c语言实现)
[打印本页]
作者:
天空闲话
时间:
3 天前
标题:
数据布局 之 【顺序表实现】(c语言实现)
剧烈发起看完上一期博客之后再来看这一期
:
数据布局之【顺序表简介】
3.实现顺序表的增删查改
静态顺序表的缺陷较大,
所以下面展示的是动态顺序表的相关函数
3.1初始化
布局体变量创建之后,起首初始化一下才好
#define INIT_CAPACITY 10
void SLINIT(SL* ps)
{
assert(ps);
ps->arr = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);
ps->capacity = INIT_CAPACITY;
ps->size = 0;
}
复制代码
1.
传入的指针不能为空时
为了节约调试时间,断言一下
2.初始化的时候,
传入的是布局体的地点
由于
传址传参
,才气根据地点改变相应的值
传值传参
,会导致“形参改变,实参稳定”的情况
传值传参时,形参是实参的临时拷贝
3.2烧毁顺序表
动态开发部分内存
当不再利用的时候,需要程序员自动释放
void SLDestroy(SL* ps)
{
assert(ps);
free(ps->arr);
ps->capacity = 0;
ps->size = 0;
}
复制代码
1.
传入的指针不能为空时
为了节约调试时间,断言一下
2.烧毁的时候,
传入的是布局体的地点
由于
传址传参
,才气根据地点改变相应的值
传值传参
,会导致“形参改变,实参稳定”的情况
传值传参时,形参是实参的临时拷贝
3.3打印顺序表
编写这个函数之后
有利于我们调试自己的程序
void SLPrint(SL* ps)
{
assert(ps);
//每个数据元素之后有空格
for (int i = 0; i < ps->size; ++i)
{
printf("%d ", ps->arr[i]);
}
//打印完一行就换行
print("\n");
}
复制代码
(1)打印的时候,
传入的是布局体的地点
由于
只管传值与传址传参都可以实现打印的功能
但是
传值传参会拷贝布局体的内容
如果布局体太大,可能会导致栈溢出等现象
而传址传参则不会有这种可能
(2)
传入的指针不能为空时
为了节约调试时间,断言一下
3.4顺序表扩容
当
有效数据个数与空间容量相等
的时候
就可以考虑
扩容
了
void CheckCapacity(SL* ps)
{
assert(ps);
if (ps->capacity == ps->size)
{
ps->capacity *= 2;
SLDataType* temp = (SLDataType*)realloc(ps->arr, sizeof(SLDataType) * (ps->capacity));
if (temp == NULL)
return;
ps->arr = temp;
}
}
复制代码
(1).扩容的时候,
传入的是布局体的地点
由于
传址传参
,才气根据地点改变相应的值
传值传参
,会导致“形参改变,实参稳定”的情况
传值传参时,形参是实参的临时拷贝
(2).
传入的指针不能为空时
为了节约调试时间,断言一下
(3).
realloc
扩容可能会出现
异地扩容
的情况
所以需要将扩容乐成的新指针
temp
赋值给布局体中的指针
arr
(4)扩容时,一般扩充到原来的两倍就可以了
3.5增删查改 之【头插】
头插
的意思就是
将数据插入到顺序表的最前面
void PushFront(SL* ps, SLDataType x)
{
//检查是否为空
assert(ps);
//检查是否需要扩容
CheckCapacity(ps);
//实现头插
int end = ps->size - 1;
while (end >= 0)
{
(ps->arr)[end + 1] = (ps->arr)[end];
end--;
}
(ps->arr)[0] = x;
(ps->size)++;
}
复制代码
(1)头插的时候,
传入的是布局体的地点
由于
传址传参
,才气根据地点改变相应的值
传值传参
,会导致“形参改变,实参稳定”的情况
传值传参时,形参是实参的临时拷贝
(2)
传入的指针不能为空时
为了节约调试时间,断言一下
(3)为了防止越界访问,即空间不够的情况
先
检查空间容量
(4)
从后往前遍历
整个数组,
将数据
从前往后移动
一个单元
如许就可以
空出 头 的位置
(5)注意
有效数据个数要改变
3.6增删查改 之【头删】
头删
的意思就是
将顺序表最前面的数据删除
void PopFront(SL* ps)
{
//检查为空
assert(ps);
//检查有效数据个数
assert(ps->size > 0);
//实现头删
int begin = 1;
while (begin < ps->size)
{
(ps->arr)[begin - 1] = (ps->arr)[begin];
++begin;
}
(ps->size)--;
}
复制代码
(1)头删的时候,
传入的是布局体的地点
由于
传址传参
,才气根据地点改变相应的值
传值传参
,会导致“形参改变,实参稳定”的情况
传值传参时,形参是实参的临时拷贝
(2)
传入的指针不能为空时
为了节约调试时间,断言一下
(3) 顺序表中必须要有数据
即
ps->size > 0
时
才气举行删除操作
不然会出现未界说行为
(4)
从前往后
遍历整个数组,
将数据
从后往前
移动一个单元
(5) 注意
有效数据个数要改变
3.7增删查改 之【尾插】
尾插
的意思就是
将数据插入到顺序表的最反面
void PushBack(SL* ps, SLDataType x)
{
//检查是否为空
assert(ps);
//检查是否需要扩容
CheckCapacity(ps);
//实现尾插
(ps->arr)[ps->size] = x;
(ps->size)++;
}
复制代码
(1)有效数据个数
ps->size
正好是
顺序表最反面的
下标
(2)注意)有效数据个数变化
3.8增删查改 之【尾删】
尾删
的意思就是
将顺序表最反面的数据删除
void PopBack(SL* ps)
{
//检查为空
assert(ps);
//检查有效数据个数
assert(ps->size > 0);
//实现尾删
(ps->size)--;
}
复制代码
(1)让有效数据个数直接减一即可
直接不访问就好了
有效数据个数为0,插入N个数据时,
头插
的时间复杂度:O(N^2)
尾插
的时间复杂度:O(N)
有效数据个数为N,删除N个数据时,
头删
的时间复杂度:O(N^2)
尾删
的时间复杂度:O(1)
3.9增删查改 之【有效范围内插入】
有效范围内插入
的意思就是
将数据插入到顺序表当中
0<= 下标 <= (ps->size)
如许,
头插尾插也包罗在内了
void Insert(SL* ps, int pos, SLDataType x)
{
//检查是否为空
assert(ps);
//检查下标位置
assert(pos >= 0 && pos <= ps->size);
//检查是否需要扩容
CheckCapacity(ps);
//实现插入
int end = ps->size - 1;
while (end >= pos)
{
(ps->arr)[end + 1] = (ps->arr)[end];
--end;
}
(ps->arr)[pos] = x;
(ps->size)++;
}
复制代码
(1)从后往前遍历,实现移动即可
3.10增删查改 之【有效范围内删除】
有效范围内删除
的意思就是
将顺序表当中的数据删除
0<= 下标 <= (ps->size - 1)
如许,
头删尾删也包罗在内了
void Erase(SL* ps, int pos)
{
//检查为空
assert(ps);
//检查下标位置
assert(pos >= 0 && pos < ps->size);
//实现删除
int begin = pos + 1;
while (begin < ps->size)
{
ps->arr[begin - 1] = ps->arr[begin];
++begin;
}
ps->size--;
}
复制代码
(1)注意下标位置的范围
(2)从前向后遍历,从后向前移动
如许,你只需要写
Insert 和 Erase 两个函数
就可以实现
头删尾删头插尾插等
了
3.11增删查改 之【有效范围内查找】
有效范围内查找
的意思就是
在顺序表当中查找想要的值
没有本事可言,直接暴力查找就好
int Find(SL* ps, SLDataType x)
{
for (int i = 0; i < ps->size; ++i)
{
if (ps->arr[i] == x)
return i;
}
return -1;
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4