目录
编辑
1. 顺序表的概念及结构
2. 接口的实现
2.1 顺序表的初始化
2.2 检查顺序表容量是否已满
2.3 顺序表的尾插
编辑
2.4 顺序表的尾删
2.5 顺序表的头插
2.6 顺序表的头删
2.7 顺序表在pos位置插入
2.8 顺序表在pos位置删除
2.9 顺序表的查找
2.10 顺序表的销毁
2.11 顺序表的打印
3. 我在实现顺序表时的测试代码
4. 完结散花
悟已往之不谏,知来者犹可追
创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免费的赞哟~
1. 顺序表的概念及结构
顺序表是用一段物理地址连续的存储单元以此存储数据的线性结构,一般情况下用数组存储。在数组上完成数据的增删查改~
1. 静态顺序表:用指定长度数组存储元素~
2. 动态顺序表:用动态开辟的数组存储~
2. 接口的实现
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空 间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间 大小,所以下面我们实现动态顺序表。
我们创建一个Test.h里面包含了所有的接口函数声明和各种头文件的声明~
这样我们一个一个实现,正所谓天下难事必做于细~
#define _CRT_SECURE_NO_WARNINGS #pragma once//避免头文件的多次包含 #include<stdio.h> #include<assert.h> #include<stdlib.h> typedef int SLDataType;//便于类型的改动 //定义一个动态顺序表的结构体变量 typedef struct SeqList { SLDataType* arr; size_t num;//记录有效数据的个数 size_t capacity;//该顺序表的容量大小 }SL;//将该结构体类型重命名为SL //加入增删查改接口 //1. 顺序表初始化 void SeqListInit(SL* p); //2. 检查顺序表容量是否已满 void CheckSeqList(SL* p); //3. 顺序表的尾插 void SeqListPushBack(SL* p, SLDataType x); //4. 顺序表的尾删 void SeqListPopBack(SL* p); //5. 顺序表的头插 void SeqListPushFront(SL* p, SLDataType x); //6. 顺序表的头删 void SeqListPopFront(SL* p); //7. 顺序表在pos位置插入 void SeqListInsert(SL* p, size_t pos,SLDataType x); //8. 顺序表在pos位置删除 void SeqListErase(SL* p, size_t pos); //9. 顺序表的查找 int SeqListFind(SL* p,SLDataType x);//如果该数字存在则返回该数字的下标,否则返回-1 //10 顺序表的销毁 void SeqListDestory(SL* p); //11. 顺序表的打印 void SeqListPrint(SL* p);
我们将所有函数的实现放在SeqList.c文件中~
2.1 顺序表的初始化
//1. 顺序表初始化
void SeqListInit(SL* p)
{
assert(p);//判断指针的有效性
p->arr = NULL;
p->capacity = 0;
p->num = 0;
}
注意我们这里一定要传址调用~
2.2 检查顺序表容量是否已满
注释写的很详细了,这里就不做过多的解释~
//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p)
{
assert(p);//判断指针的有效性
if (p->num == p->capacity)
{
size_t newcapacity=p->capacity == 0 ? p->capacity = 4 : p->capacity * 2;
//如果原来没有空间,就给上4,有的话就扩大为原来的两倍
SLDataType* ptr = (SLDataType*)realloc(p->arr, newcapacity * sizeof(SLDataType));//动态扩容
if (ptr == NULL)
{
perror("realloc fail;");
return;
}
//也可以用assert断言一下
p->arr = ptr;//开辟成功将地址传给arr
p->capacity = newcapacity;//更新容量
}
}
2.3 顺序表的尾插
//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x)
{
assert(p);//判断指针的有效性
CheckSeqList(p);//尾插前先判断有没有容量或容量够不够
p->arr[p->num] = x;//尾部插入数据
p->num++;//有效数加一
}
2.4 顺序表的尾删
//4. 顺序表的尾删
void SeqListPopBack(SL* p)
{
assert(p);//判断指针的有效性
assert(p->num > 0);//断言存在有效数据
p->num--;//尾删一个数据
}
2.5 顺序表的头插
//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x)
{
assert(p);//判断指针的有效性
CheckSeqList(p);//先判断容量是否满了
size_t end = p->num;
while (end)
{
p->arr[end] = p->arr[end - 1];//整体向后移动
end--;
}
p->arr[0] = x;//头插
p->num++;//有效数据加一
}
2.6 顺序表的头删
//6. 顺序表的头删
void SeqListPopFront(SL* p)
{
assert(p);//判断指针的有效性
assert(p->num > 0);//有数据才删除
size_t begin = 1;
while (begin<p->num)
{
p->arr[begin - 1] = p->arr[begin];//整体向前移动
begin++;
}
p->num--;// 有效数据减一
}
整体往前挪,把头覆盖~
2.7 顺序表在pos位置插入
//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x)
{
assert(p);//判断指针的有效性
assert(p->num > pos);//pos必须小于num并且大于0
CheckSeqList(p);//判断容量是否满了
for (int i = p->num; i >pos-1 ; i--)
{
p->arr[i] = p->arr[i - 1];//将pos后面的元素往后挪
}
p->arr[pos - 1] = x;//在pos位置加入数据
p->num++;//有效个数加一
}
2.8 顺序表在pos位置删除
//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos)
{
assert(p);//判断指针的有效性
assert(p->num > pos);//pos必须小于num并且大于0
assert(p->num > 0);//有数据才能删除
for (int i = pos; i <p->num; i++)
{
p->arr[i-1] = p->arr[i];//将pos后面的元素往后挪
}
p->num--;//有效个数减一
}
2.9 顺序表的查找
遍历数组查找~
//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x)//如果该数字存在则返回该数字的下标,否则返回-1
{
assert(p);//断言
for (int i = 0; i < p->num; i++)
{
if (p->arr[i] == x)
{
return i;//查到返回下标
}
}
return -1;//没有查到
}
2.10 顺序表的销毁
//10 顺序表的销毁
void SeqListDestory(SL* p)
{
assert(p);//判断指针的有效性
free(p->arr );//释放动态内存开辟的空间
p->arr = NULL;
p->capacity = 0;//容量置为0
p->num = 0;//有效个数置为0
}
2.11 顺序表的打印
//11. 顺序表的打印
void SeqListPrint(SL* p)
{
assert(p);//判断指针的有效性
if (p->num == 0)
{
printf("顺序表为空!\n");
return;
}
for (int i = 0; i < p->num; i++)
{
printf("%d ", p->arr[i]);//打印数据
}
printf("\n");
}
3. 我在实现顺序表时的测试代码
我创建了一个Test.c来测试各个部分的功能~
#define _CRT_SECURE_NO_WARNINGS
#include"Test.h"
void TestSeqList()
{
SL s1;
SeqListInit(&s1);//初始化
SeqListPushBack(&s1, 1);//尾插一个1;
SeqListPushBack(&s1, 2);//尾插一个2;
SeqListPushBack(&s1, 3);//尾插一个3;
SeqListPushBack(&s1, 4);//尾插一个4;
SeqListPushBack(&s1, 5);//尾插一个5;
SeqListInsert(&s1, 3, 9);//在第三个位置插入9
SeqListErase(&s1, 3);//删除第三个位置
int ret=SeqListFind(&s1, 3);
if (ret != -1)
printf("你要查找的数据的下标为:%d\n", ret);
else
printf("抱歉,你要查找的数据没有找到!\n");
//SeqListPopBack(&s1);//尾删一个数据
//SeqListPushFront(&s1,30);//头插一个数据
//SeqListPopFront(&s1);//头删一个数据
SeqListPrint(&s1);//打印数据
}
int main()
{
//测试顺序表
TestSeqList();
return 0;
}
4. 完结散花
好了,这期的分享到这里就结束了~
如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~
如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~
我们下期不见不散~~