赞
踩
线性表(linear list):n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储
顺序表属于线性表的其中一种。顺序表在逻辑、物理结构上是连续。顺序表底层逻辑一般是数组。(物理结构上连续是指一段物理地址连续的存储单元依次存储数据元素的结构)
顺序表分为两种:静态顺序表和动态顺序表,每一种都属于它自己的价值,在实际中。一般使用动态顺序表做的,比如我们经常用的通讯录(因为静态顺序表只适合事前知道需要多少内存的情况下,不然会出现申请多少内存问题)
当我们有所了解顺序表的结构,接下来是实现顺序表的相关接口,比如增删查改
实现的过程中,创建两个源文件和一个头文件,分别为实现顺序表功能和测试顺序表功能,头文件一般用于声明函数(将在文章结尾处,贴出test.c文件)
注意:头文件只负责声明,在源文件中就是预编译阶段将多个头文件整合到一起
小技巧:
void SLInit(SL* phead)
{
assert(phead);
phead->a = NULL;
phead->size = phead->capacity = 0;
}
在实现该接口时:
void SLChekckCapacity(SL* phead) { assert(phead); if (phead->size == phead->capacity) { int newcapacity =phead->capacity==0?4:phead->capacity * 2; SLDataType* pphead = (SLDataType*)realloc(phead->a, sizeof(SLDataType) * newcapacity); if (pphead == NULL) { perror("realloc fail!!"); return 1; } phead->a = pphead; phead->capacity = newcapacity; } }
在实现该接口时:
void SLPlusBack(SL*phead, SLDataType x)
{
assert(phead);
if(phead->size == phead->capacity)
SLChekckCapacity(phead);
phead->a[phead->size] = x;
phead->size++;
}
在实现该接口时:
void SLPlusFront(SL* phead, SLDataType x)
{
assert(phead);
if(phead->size == phead->capacity)
SLChekckCapacity(phead);
for (int i = phead->size; i >0; i--)
{
phead->a[i] = phead->a[i - 1];
}
phead->a[0] = x;
phead->size++;
}
在实现该接口时:
void SLPopBack(SL* phead)
{
assert(phead);
assert(phead->a);
phead->size--;
}
在实现该接口时:
void SLPopFront(SL* phead)
{
assert(phead);
assert(phead->a);
for (int i = 0; i < phead->size-1; i++)
{
phead->a[i] = phead->a[i + 1];
}
phead->size--;
}
在实现该接口时:
为了实现对某个位置进行修改,需要利用到顺序表中查找接口
int SLFind(SL* phead, SLDataType x)
{
assert(phead);
assert(phead->a);
for (int i = 0; i < phead->size; i++)
{
if (phead->a[i] == x)
return i;
}
return -1;
}
在实现该接口时:
void SLInsert(SL* phead, int pos, SLDataType x)
{
assert(phead);
assert(0 <= pos && pos <= phead->size);
SLChekckCapacity(phead);
for (int i = phead->size; i>pos;i--)
{
phead->a[i] = phead->a[i-1];//pos+1 pos-->注意覆盖的顺序,向后就是后面开始
}
phead->a[pos] = x;
phead->size++;
}
在实现该接口时:
void SLErase(SL* phead, int pos)
{
assert(phead);
assert(pos >= 0 && pos < phead->size);
for (int i = pos;i<phead->size-1;i++)
{
phead->a[i] = phead->a[i + 1];
}
phead->size--;
}
在实现该接口时:
顺序表实现任意位置插入、插入跟头尾插删是类型的。但是上面的操作相当于基础,也是需要学习的(只有学会1+1,才能学会7+8)
bool SLEmpty(SL*phead)
{
assert(phead);
assert(phead->a);
return phead->size==0;
}
void SLPrintData(SL*phead)
{
assert(phead);
for (int i = 0; i < phead->size; i++)
{
printf("%d ", phead->a[i]);
}
printf("\n");
}
void SLDestory(SL*phead)
{
assert(phead);
if (phead->a)
{
free(phead->a);//free该前顺序表的动态开辟的空间
phead->a = NULL;
phead->size = phead->capacity = 0;
}
}
补充:贴出test.c文件
test.c #define _CRT_SECURE_NO_WARNINGS 1 #include "Seqlist.h" void test4() { SL phead; SLInit(&phead); SLPlusBack(&phead, 3); SLPlusBack(&phead, 4); SLPlusBack(&phead, 5); SLPrintData(&phead); SLInsert(&phead,1, 100);//这个pos是下标,pos之后插入 SLPrintData(&phead); SLErase(&phead,1); SLPrintData(&phead); int pos = SLFind(&phead, 3);//可以找到当前下标 //实现定位 SLDestory(&phead); } int main() { test4(); return 0; }
只学习一种数据结构不能应付在实际中的许多问题,并且顺序表也有自身的优点和缺点->在链表部分,会总结之间的差异
顺序表的优点:
顺序表的缺点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。