阅读本文需掌握的知识:
- 多个文件协同操作
- typedef、realloc函数、指针、结构体
- 数组空间存储结构
- C语言基本语法
计算机世界中存在无穷无尽的数据,如果想要高效地利用这些数据,我们必须对数据作出一定管理规则,将相同特性的数据按照一定物理结构存储在一块方便取用,这就叫做数据结构。
我们已经学习了最基本的数据结构:数组,有了数组的概念,我们今天来拓展一种新的数据结构——顺序表
顺序表的概念:
顺序表即具有相同特性的一类数据结构的统称,底层结构为数组,因此它的逻辑结构成线性,物理结构也呈线性,分为静态顺序表和动态顺序表
//静态顺序表
struct SeqList
{
int a[10];
int size;
}
//动态顺序表
struct SeqList
{
int* a;
int size;
int capacity;
静态顺序表代码简洁,无需考虑空间上的扩容与缩小,但是弊端也很明显,空间大了造成内存浪费,空间小了造成数据丢失(内存不够);动态顺序表空间大小灵活,可大可小视情况而定,但是代码书写较为繁琐。
本文下述代码段均以实现动态顺序表为例
顺序表的实现:
根据实际经验我们可以知道一个合格的顺序表所具备的操作应该有头插、尾插、头删、尾删、销毁、创建初始化一系列步骤
其中插入步骤最为复杂,我们率先讨论,插入数据之前应先考虑两种情况:空间足够or空间不足,倘若空间不足则需要扩容,空间足够则只需要在原有空间上进行数据移位即可
提示:所有函数操作需要传址调用(传值调用只是临时拷贝,不会对实参作出任何修改)
头文件的定义
SeqList.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//定义顺序表
typedef int Date;//数据类型
typedef struct SeqList
{
Date* a;//空间起始地址
int size;//有效数据个数
int capacity;//空间大小
}SL;
void init(SL*ps);//初始化
void destroy(SL*ps);//销魂
void head_insert(SL*ps,Date x);//增
void tail_insert(SL*ps,Date x);
void head_pop(SL*ps);//删
void tail_pop(SL*ps);
void print(SL*ps);//输出
bool isempty(SL*ps);//判断是否为空
void enlarge(SL*ps);//扩容
函数具体实现:
SeqList.c
#include "SeqList.h"
void init(SL* ps)
{
ps->a=NULL;
ps->size=ps->capacity=0;
}
void destroy(SL* ps)
{
if(ps->a)
free(ps);
ps->a=NULL;
ps->size=ps->capacity=0;
}
void enlarge(SL* ps)
{
assert(ps);
if(ps->size==ps->capacity)
{
int newcap=ps->capacity==0?4;capacity*2;
//规定每一次扩容2倍
Date* tmp=(Date*)realloc(ps->a,newcap*sizeof(Date));
assert(tmp);
ps->a=tmp;ps->capacity=newcap;
}
}
void tail_insert(SL*ps,Date x)
{
assert(ps);
enlarge();
ps->a[size]=x;
ps->size++;
}
void head_insert(SL* ps,Date x)
{
assert(ps);
enlarge();
for(size_t i=size;i>0;i--)
{
ps->a[i]=ps->a[i-1];
}
ps->a[0]=x;
ps->size++;
}
void tail_pop(SL* ps)
{
assert(ps);
assert(!isempty(ps));
ps->size--;
}
void head_pop(SL* ps)
{
assert(ps);
assert(!isempty(ps));
for(size_t i=0;i<=size-2;i++)
{
ps->a[i]=ps->a[i+1];
}
ps->size--;
}
bool isempty(SL* ps)
{
assert(ps);
return ps->size==0;
}
void print(SL*)
{
for(size_t i=0;i<size;i++)
printf("%d ",ps->a[i]);
printf("\n");
}
测试函数实现:
test.c
include "SeqList.h"
void test()
{
SL s1;//先声明结构体变量!
init(&s1);
tail_insert(&s1, 1);
tail_insert(&s1, 2);
tail_insert(&s1, 3);
tail_insert(&s1, 4);
print(&s1);
head_insert(&s1, 5);
head_insert(&s1, 6);
head_insert(&s1, 7);
head_insert(&s1, 8);
print(&s1);
tail_pop(&s1);
print(&s1);
head_pop(&s1);
print(&s1);
destroy(&s1);
}
int main()
{
test();
return 0;
}
效果如图