数据结构之顺序表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之顺序表相关的知识,希望对你有一定的参考价值。

顺序表(SeqList)是在计算机内存中以数组形式保存的线性数据结构,同时具有连续的物理存储空间。元素在顺序表中的位置称为索引(inde

x)。顺序表大致分为静态顺序表和动态顺序表,前者的容量一经定义就无法改变,后者可随时进行容量调整。动态顺序表在数组的基础上具有容量检测和调整等其他功能接口,使数组的使用更加丰富和方便。


逻辑结构

顺序表的逻辑结构为线性结构,各个元素在逻辑结构上相邻。

数据结构之顺序表_顺序表



物理结构

顺序表的物理结构为线性结构,各个元素在内存中相邻存放。

数据结构之顺序表_顺序表_02



顺序表定义

#define DEFAULT_CAPA 20//初始容量
#define EXP_SZ 20//增容大小

typedef int SeqListDataTp;//顺序表数据类型

typedef struct SeqList

SeqListDataTp* data;
int size;//记录当前数据数量
int capacity;//记录当前最大容量
SeqList;

void SeqListInit(SeqList* sl);
void SeqListPushBack(SeqList* sl, const SeqListDataTp x);
void SeqListPopBack(SeqList* sl);
void SeqListPushFront(SeqList* sl, const SeqListDataTp x);
void SeqListPopFront(SeqList* sl);
int SeqListSz(SeqList* sl);
bool SeqListEmpty(SeqList* sl);
int SeqListFind(SeqList* sl, const SeqListDataTp aim);
void SeqListModify(SeqList* sl, const int pos, const SeqListDataTp aim);
void SeqListDel(SeqList* sl, const int pos);
void SeqListInsert(SeqList* sl, const int pos, const SeqListDataTp x);
void SeqListClear(SeqList* sl);
void SeqListDestory(SeqList* sl);


接口实现


小组件

容量检查和调整。该组件会在顺序表容量不足时进行扩容操作,在容量冗余时进行缩容操作,以达到尽量节省空间的目的。

void CheckCap(SeqList* sl)

assert(sl);
if (sl->size == sl->capacity)

SeqListDataTp* tmp = (SeqListDataTp*)realloc(sl->data,
sizeof(SeqListDataTp) * (EXP_SZ + sl->capacity));
if (tmp == NULL)

perror("Check::realloc");

else

sl->data = tmp;
sl->capacity += EXP_SZ;


else if (sl->capacity - sl->size > EXP_SZ)

SeqListDataTp* tmp = (SeqListDataTp*)realloc(sl->data,
sizeof(SeqListDataTp) * (sl->size + EXP_SZ));
if (tmp == NULL)

perror("Check::realloc");

else

sl->data = tmp;
sl->capacity = sl->size + EXP_SZ;


初始化顺序表

void SeqListInit(SeqList* sl)

assert(sl);
sl->data = (SeqListDataTp*)malloc(sizeof(SeqListDataTp) *
DEFAULT_CAPA);
if (sl->data == NULL)

perror("SeqListInit::malloc:");

else

sl->size = 0;
sl->capacity = DEFAULT_CAPA;

头部插入/删除

void SeqListPushBack(SeqList* sl, const SeqListDataTp x)//头插

assert(sl);
CheckCap(sl);//容量检查和调整
sl->data[sl->size] = x;
sl->size++;


void SeqListPopBack(SeqList* sl)//头删

assert(sl);
if (sl->size == 0)//顺序表为空

printf("NULL\\n");
return;

sl->data[sl->size - 1] = 0;
sl->size--;
CheckCap(sl);

尾部插入/删除

void SeqListPushFront(SeqList* sl, const SeqListDataTp x)

assert(sl);
CheckCap(sl);
memmove(sl->data + 1, sl->data,
sizeof(SeqListDataTp) * sl->size);
sl->data[0] = x;
sl->size++;


void SeqListPopFront(SeqList* sl)

assert(sl);
if (sl->size == 0)

printf("NULL\\n");
return;

memmove(sl->data, sl->data + 1,
sizeof(SeqListDataTp) * sl->size);
sl->data[sl->size - 1] = 0;
sl->size--;
CheckCap(sl);

显示当前数据个数

int SeqListSz(SeqList* sl)

assert(sl);
return sl->size;

判断是否为空

bool SeqListEmpty(SeqList* sl)

assert(sl);
return sl->size == 0;

显示当前最大容量

int SeqListCap(SeqList* sl)

assert(sl);
return sl->capacity;

寻找指定的值

int SeqListFind(SeqList* sl, const SeqListDataTp aim)

for (int i = 0; i < sl->size; i++)

if (sl->data[i] == aim)

return i;


return -1;//找不到返回-1

在指定位置插入数据

void SeqListInsert(SeqList* sl, const int pos, const SeqListDataTp x)

assert(sl);
assert(pos <= (sl->size - 1));
CheckCap(sl);
memmove(sl->data + pos + 1, sl->data + pos,
sizeof(SeqListDataTp) * (sl->size - pos));
sl->data[pos] = x;
sl->size++;

修改指定位置的数据

void SeqListModify(SeqList* sl, const int pos, const SeqListDataTp aim)

assert(sl);
sl->data[pos] = aim;

删除指定位置的数据

void SeqListDel(SeqList* sl, const int pos)

assert(sl);
if (sl->size == 0)

printf("NULL\\n");
return;

memmove(sl->data + pos, sl->data + pos + 1,
sizeof(SeqListDataTp) * (sl->size - pos - 1));
sl->data[sl->size - 1] = 0;
sl->size--;
CheckCap(sl);

清理顺序表

void SeqListClear(SeqList* sl)

assert(sl);
memset(sl->data, 0, sizeof(SeqListDataTp) * sl->size);
sl->size = 0;
CheckCap(sl);

销毁顺序表

void SeqListDestory(SeqList* sl)

assert(sl);
free(sl->data);
sl->data = NULL;//置空,避免产生野指针
sl->size = 0;
sl->capacity = 0;


顺序表的缺陷

从上面顺序表的实现中可以看到,顺序表有以下缺陷:

  1. 顺序表增容会有一定的性能消耗,且顺序表存在空间浪费现象
  2. 进行头部插入/删除操作时,需要移动其他所有数据,效率较低O(N))。这个问题其实是顺序表的存储结构造成的。

以上是关于数据结构之顺序表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构初阶:动态顺序表的功能实现(用C语言实现,附图分析)

单链接表的实现之从尾部插入节点

线性表:顺序储存结构

线性表:顺序储存结构

python数据结构与算法

数据结构线性表之顺序表ArrayList