文章目录
顺序表
观看这里的uu建议先看时间复杂度与空间复杂度
时间复杂度与空间复杂度点击这里
一、前言
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列等。
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
顺序表是典型的线性表之一,以数组的形式存储。
二、顺序表
1·顺序表的概念
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表本质上可以视为数组,其不仅在逻辑上是线性结构的,而且其在物理结构上也是连续存储的,顺序表在数组的基础上引入了静态和动态的概念。
2·静态顺序表及其接口函数
静态顺序表就是给定存储数据的大小来存储数据,存储已满就禁止插入数据,静态顺序表很难确定给定的存储大小是多少,如果给定的存储太小,那么就不够存储的需求;如果给定的存储太大,那么就会浪费空间,所以一般不用静态顺序表存储数据。
静态顺序表头文件Seqlist.h的声明如下:
#pragma once //防止头文件被重复包含
#ifndef _Seqlist_H_
#define _Seqlist_H_
#include <cstddef> //使用size_t需包含此头文件
#define N 1000 //静态顺序表固定的存储容量
//重新自定义int标识符,后续存储其它数据类型元素可以方便修改
typedef int SLDataType;
//静态顺序表
typedef struct Seqlist
{
SLDataType a[N]; //存储数据的数组
int size; //表示数组中目前存储数据的个数
}SL;
// 基本增删查改接口函数
//这些接口函数以指针形式接收是因为函数中的形参改变并不会改变实参的数值
//只有传递指针后对地址空间解引用才能实现实参的修改
// 顺序表初始化
void SeqListInit(SL * ps);
// 顺序表销毁
void SeqListDestory(SL* ps);
// 顺序表打印
void SeqListPrint(SL* ps);
// 检查空间,如果存储已满,进行扩容
void CheckCapacity(SL* ps);
// 顺序表尾插
void SeqListPushBack(SL* ps, SL x);
// 顺序表尾删
void SeqListPopBack(SL* ps);
// 顺序表头插
void SeqListPushFront(SL* ps, SLDataType x);
// 顺序表头删
void SeqListPopFront(SL* ps);
// 顺序表查找
int SeqListFind(SL* ps, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SL* ps, size_t pos);
#endif
静态顺序表的接口函数实现方式与动态顺序表大同小异,这里不做赘述,在动态顺序表中详细说明。
3·动态顺序表及其接口函数
动态顺序表可以根据需求来扩容存储空间,比静态顺序表灵活,因此动态顺序表被广泛使用。
动态顺序表头文件Seqlist.h的声明如下:
#pragma once //防止头文件被重复包含
#ifndef _Seqlist_H_
#define _Seqlist_H_
#include <cstddef> //使用size_t需包含此头文件
#include <stdio.h>
#include <stdlib.h>
//重新自定义int标识符,后续存储其它数据类型元素可以方便修改
typedef int SLDataType;
//动态顺序表
typedef struct Seqlist
{
SLDataType* a; //后续动态开辟空间的指针
int size; //表示当前空间中目前存储数据的个数
int capacity; //空间实际能存储数据容量大小
}SL;
// 基本增删查改等接口函数
/* 这些接口函数以指针形式接收是因为函数中的形参改变并不会改变实参的数值
只有传递指针后对地址空间解引用才能实现实参的修改*/
// 顺序表初始化
void SeqListInit(SL* ps);
// 顺序表销毁
void SeqListDestory(SL* ps);
// 顺序表打印
void SeqListPrint(SL* ps);
// 检查空间,如果存储已满,进行扩容
void CheckCapacity(SL* ps);
// 顺序表尾插
void SeqListPushBack(SL* ps, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SL* ps);
// 顺序表头插
void SeqListPushFront(SL* ps, SLDataType x);
// 顺序表头删
void SeqListPopFront(SL* ps);
// 顺序表查找
int SeqListFind(SL* ps, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SL* ps, size_t pos);
#endif
三、动态顺序表的实现
1·初始化、打印、扩容与销毁
初始化函数在Seqlist.c中如下:
//顺序表初始化
void SeqListInit(SL* ps)
{
ps->a = NULL;
ps->capacity = ps->size = 0