一,顺序表的定义
顺序表是用一段
物理地址连续
的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
1.
静态顺序表:使用定长数组存储元素
。
2.
动态顺序表:使用动态开辟的数组存储
动态定义:
typedef double SLDatatype;//定义存储数据类型,方便更换类型
typedef struct Seqlist
{
SLDatatype* a;
int size;//表示数组实际存储数据个数
int capacity;//表述数组最大能够存储个数
}SL;//重命名为SL
//接口函数
void SeqListInit(SL* ps);//创建顺序表
void SeqListPushBack(SL* ps, SLDatatype x);//尾插
void SeqListPopBack(SL* ps);//尾删
void SeqListPushFront(SL* ps, SLDatatype x);//头插
void SeqListPopFront(SL* ps);//头删
尾插:由于时动态开辟内存,所以在开辟时有三种情况:
1.数组还不存在,需要从0开始创建
2.数组内存不够用,需要进一步增容
3.数组内存足够,无需调整
void SeqListPushBack(SL* ps, SLDatatype x)//尾插
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->a == 0 ? 4 : ps->capacity * 2;//使用三目操作符表示:如果等于0不存在则从0开辟4,如果不是则扩容2倍
SLDatatype* tmp = (SLDatatype*)realloc(ps->a, newcapacity * sizeof(SLDatatype));
if (tmp == NULL)
{
printf("开辟内存失败");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->size] = x;
ps->size++;
}
封装一个增容函数:
void SeqListCheckCapacity(SL* ps)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->a == 0 ? 4 : ps->capacity * 2;//使用三目操作符表示:如果等于0不存在则从0开辟4,如果不是则扩容2倍
SLDatatype* tmp = (SLDatatype*)realloc(ps->a, newcapacity * sizeof(SLDatatype));
if (tmp == NULL)
{
printf("开辟内存失败");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
}
尾删:由于可能为空,需要判定,另外只需要size--,让数组访问不到就可以达到删除的效果
void SeqListPopBack(SL* ps)//尾删
{
assert(ps->size>0);
ps->size--;
}
头插:先把元素往后挪,然后再添加。由于要访问到end+1位元素,所以先进行增容检查,否则会发生越界访问,注意如果从前往后挪则会发生覆盖
void SeqListPushFront(SL* ps, SLDatatype x)//头插
{
SeqListCheckCapacity(ps);
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[0] = x;
ps->size++;
}
头删:先判定是否为空,然后从前往后挪元素
void SeqListPopFront(SL* ps)//头删
{
assert(ps->size > 0);
int begin = 1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
完整代码分为定义的头函数,接口实现两个部分,接口实现部分包括了打印销毁等别的基础接口
定义部分:list.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#pragma once //只定义一次,减少重复定义
//静态数组
#define N 1000//定义数组大小
//typedef double SLDatatype;//定义存储数据类型,方便更换类型
//
//typedef struct Seqlist
//{
// SLDatatype a[N];
// int size;//表示数组存储数据大小
//}SL;//重命名为SL
//
接口函数
//void SeqListInit(SL* ps);//创建顺序表
//void SeqListPushBack(SL* ps,SLDatatype x);//尾插
//void SeqListPopBack(SL* ps);//尾删
//void SeqListPushFront(SL* ps,SLDatatype x);//头插
//void SeqListPopFront(SL* ps);//尾删
//动态数组
typedef double SLDatatype;//定义存储数据类型,方便更换类型
typedef struct Seqlist
{
SLDatatype* a;
int size;//表示数组实际存储数据个数
int capacity;//表述数组最大能够存储个数
}SL;//重命名为SL
//接口函数
void SeqListInit(SL* ps);//创建顺序表
void SeqListPushBack(SL* ps, SLDatatype x);//尾插
void SeqListPopBack(SL* ps);//尾删
void SeqListPushFront(SL* ps, SLDatatype x);//头插
void SeqListPopFront(SL* ps);//头删
void SeqListPrint(SL* ps);
void SeqListDestroy(SL* ps);
void SeqListCheckCapacity(SL* ps);
接口实现部分:list.c
#define _CRT_SECURE_NO_WARNINGS
#include "list.h"
void SeqListInit(SL* ps)//创建顺序表
{
ps->a = NULL;
ps->size = ps->capacity = 0;
}
void SeqListDestroy(SL* ps)
{
free(ps->a);
ps->a = NULL;
ps->capacity = ps->size = 0;
}
void SeqListPrint(SL* ps)
{
for (int i = 0; i < ps->size; i++)
{
printf("%f ", ps->a[i]);
}
printf("\n");
}
void SeqListCheckCapacity(SL* ps)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->a == 0 ? 4 : ps->capacity * 2;//使用三目操作符表示:如果等于0不存在则从0开辟4,如果不是则扩容2倍
SLDatatype* tmp = (SLDatatype*)realloc(ps->a, newcapacity * sizeof(SLDatatype));
if (tmp == NULL)
{
printf("开辟内存失败");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
}
void SeqListPushBack(SL* ps, SLDatatype x)//尾插
{
SeqListCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
void SeqListPopBack(SL* ps)//尾删
{
assert(ps->size>0);
ps->size--;
}
void SeqListPushFront(SL* ps, SLDatatype x)//头插
{
SeqListCheckCapacity(ps);
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[0] = x;
ps->size++;
}
void SeqListPopFront(SL* ps)//头删
{
assert(ps->size > 0);
int begin = 1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}