在数据结构中,顺序表无疑是十分重要的,作为线性表的一员,在生活中也有很多的应用。这篇博客介绍一下关于顺序表的小知识。
首先介绍一下顺序表的概念:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
- 静态顺序表:使用定长数组存储。
- 动态顺序表:使用动态开辟的数组存储。
下面给出动态顺序表几大接口的实现:`
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
typedef struct Seqlist
{
SLDataType* _a;
size_t _size;
size_t _capacity;
}SeqList;
void SeqListInit(SeqList *ps);//初始化
void SeqListDestory(SeqList *ps);//对空间的释放
void SeqListPrint(SeqList *ps);//打印
void SeqListCheckCapacity(SeqList *ps);//对空间进行扩容
void SeqListPushBack(SeqList *ps, SLDataType x);//尾插法
void SeqListPopBack(SeqList *ps);//尾删法
void SeqListPushFront(SeqList *ps, SLDataType x);//头插法
void SeqListPopFront(SeqList *ps);//头删法
int SeqListFind(SeqList *ps, SLDataType x);//返回数组的下标
void SeqListInsert(SeqList *ps, size_t pos, SLDataType x);//在任意位置插入元素
void SeqListErase(SeqList *ps, size_t pos);//在任意位置删除元素
void SeqListRemove(SeqList *ps, SLDataType x);//给定X自己找
#endif
上面是几大接口的功能,以及包含一个最基本动态顺序表信息的结构体,动态的开辟.
下面给出几大接口的实现:(每个接口的功能我都有注释)
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void SeqListInit(SeqList* ps)
{
assert(ps);
ps->_a = NULL;
ps->_size = 0;
ps->_capacity = 0;
}
void SeqListDestory(SeqList *ps)
{
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_size = 0;
}
void SeqListPushBack(SeqList *ps, SLDataType x)//尾插法
{
assert(ps);
SeqListCheckCapacity(ps);
ps->_a[ps->_size] = x;
ps->_size++;
}
void SeqListPopBack(SeqList *ps)//尾删法
{
assert(ps&&ps->_size>0);
//ps->_a[ps->_size - 1] = 0;
ps->_size--;
}
void SeqListPushFront(SeqList *ps, SLDataType x)//头插法,先处理空间不足问题,后挪动数据
{
assert(ps);
SeqListCheckCapacity(ps);
int end = ps->_size - 1;
for (; end >= 0; --end)
{
ps->_a[end + 1] = ps->_a[end];
}
ps->_a[0] = x;
ps->_size++;
}
void SeqListPopFront(SeqList *ps)//头删法
{
assert(ps&&ps->_size>0);
for (size_t i = 0; i < ps->_size - 1; ++i)
{
ps->_a[i] = ps->_a[i + 1];
}
for (size_t i = 1; i < ps->_size; ++i)
{
ps->_a[i - 1] = ps->_a[i];
}
ps->_size--;
/*size_t b = ps->_size - 2;
for (; b>= 0; b--)
{
ps->_a[b - 1] = ps->_a[b];
}
ps->_size--;*/
}
void SeqListCheckCapacity(SeqList *ps)//对空间进行扩容
{
if (ps->_size >= ps->_capacity)
{
size_t newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
ps->_a = realloc(ps->_a, newcapacity * sizeof(SLDataType));
ps->_capacity = newcapacity;
}
}
void SeqListPrint(SeqList *ps)//打印
{
asseet(ps);
for (size_t i = 0; i < ps->_size; ++i)
{
printf("%d", ps->_a[i]);
}
printf("\n");
}
int SeqListFind(SeqList *ps, SLDataType x)//返回数组的下标
{
assert(ps);
for (size_t i = 0; i < ps->_size; ++i)
{
if (ps->_a[i] == x)
{
return i;
}
}
return -1;
}
void SeqListInsert(SeqList *ps, size_t pos, SLDataType x)//在任意位置插入元素
{
assert(ps);
SeqListCheckCapacity(ps);
for (size_t i =ps->_size; i > pos; --i)
{
ps->_a[ps->_size + 1] = ps->_a[ps->_size];
ps->_a[pos] = x;
}
ps->_size++;
}
void SeqListErase(SeqList *ps, size_t pos)//在任意位置删除元素
{
assert(ps);
for (size_t i = pos; i <ps->_size-1; --i)
{
ps->_a[i] = ps->_a[i+1];
}
ps->_size--;
}
void SeqListRemove(SeqList *ps, SLDataType x)//给定X自己找
{
int pos = SeqListFind(ps, x);
if (SeqListFind)(ps, x)
{
SeqListErase(ps, pos);
}
}
上面就是具体接口的实现,测试结果就不发了,给个测试函数进行简单测试即可,掌握了这几个常用的顺序表的结构,也让我们对于数据结构的一些简单关于顺序表的题可以做了。