(干货)顺序表及相关接口实现(附源码)
作者:互联网
顺序表:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组来存储,在数组上完成数据的增删查改;
顺序表一般可分为:
1、静态顺序表:使用定长数组存储;
2、动态顺序表:使用动态开辟的数组存储;
// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
// 顺序表的动态存储
typedef struct SeqList{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capacity ; // 容量空间的大小
}SeqList;
顺序表的优点:
1、可以随机访问
2、缓存的命中率较高(局部性原理) 缓存命中率即:缓存中存放的有用数据与缓存中总数据的比率
顺序表的缺点:
1、非尾部数据的插入与删除较慢,需要挪动数据,空间复杂度为O(N)
2、空间不够时,realloc()增容会带来一定的消耗与空间浪费
基本增删查改接口:
顺序表初始化: void SeqListInit(SeqList* ps, size_t capacity);
顺序表销毁:void SeqListDestroy(SeqList* ps);
顺序表打印:void SeqListPrint(SeqList* ps);
检查空间,如果满了,进行增容:void CheckCapacity(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);
顺序表在pos位置插入x: void SeqListInsert(SeqList* ps, size_t pos, SLDataType x);
顺序表删除pos位置的值: void SeqListErase(SeqList* ps, size_t pos);
具体实现:
头文件部分
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* a;//存放开辟的动态空间
size_t size;//动态空间已经使用的大小
size_t capacity;//动态空间的容纳量
}SeqList;
void SeqListInit(SeqList* ps,size_t capacity);
void SeqListDestroy(SeqList* ps);
void SeqListPrint(SeqList* ps);
void CheckCapacity(SeqList* ps);
void SeqListPushBack(SeqList* ps,SLDataType x);
void SeqListPopBack(SeqList* ps);
void SeqListPushFront(SeqList* ps, SLDataType x);
void SeqListPopFront(SeqList* ps);
void SeqListInsert(SeqList* ps, int pos, SLDataType x);
void SeqListErase(SeqList* ps, int pos);
int SeqListFind(SeqList* ps, SLDataType x);
接口实现部分
#include "SeqList.h"
#define _CRT_SECURE_NO_WARNINGS 1
//顺序表初始化
void SeqListInit(SeqList* ps,size_t capacity)
{
assert(ps);
ps->capacity = capacity;
ps->a = malloc(capacity * sizeof(SLDataType));
assert(ps->a);
ps->size = 0;
}
//顺序表销毁
void SeqListDestroy(SeqList* ps)
{
free(ps->a);
ps->a = NULL;
}
//打印顺序表
void SeqListPrint(SeqList* ps)
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size; ++i)
{
printf("%d ", ps->a[i]);
}
putchar('\n');
}
//检查顺序表容积,不够则开辟新的空间
void CheckCapacity(SeqList* ps)
{
assert(ps);
if (ps->capacity <= ps->size)
{
ps->capacity *= 2;
SLDataType* tmp = (SLDataType*)realloc(ps->a,ps->capacity * sizeof(SLDataType));
if (tmp == NULL)
{
printf("%s\n", strerror(errno));
exit(1);
}
else
ps->a = tmp;
}
}
//在顺序表尾部插入数据
void SeqListPushBack(SeqList* ps, SLDataType x)
{
//assert(ps);
//CheckCapacity(ps);
//ps->a[ps->size] = x;
//++ps->size;
SeqListInsert(ps, ps->size, x);
}
//在顺序表尾部删除数据
void SeqListPopBack(SeqList* ps)
{
//assert(ps);
//--ps->size;
SeqListErase(ps, ps->size-1);
}
//在顺序表头部插入数据
void SeqListPushFront(SeqList* ps,SLDataType x)
{
//assert(ps);
//int i = 0;
//CheckCapacity(ps);
//for (i = ps->size; i >= 1; --i)
//{
// ps->a[i] = ps->a[i - 1];//将所有数据后移一个单位
//}
//ps->a[0] = x;//将插入的数据放到头部
//++ps->size;
SeqListInsert(ps, 0, x);
}
//在顺序表头部删除数据
void SeqListPopFront(SeqList* ps)
{
//assert(ps);
//int i = 0;
//for (i = 0; i < ps->size; ++i)
//{
// ps->a[i] = ps->a[i + 1];//用后面的数据覆盖掉头部数据
//}
//--ps->size;
SeqListErase(ps, 0);
}
//在顺序表中的某一位置插入数据
void SeqListInsert(SeqList* ps,int pos,SLDataType x)
{
assert(ps && pos >= 0 && pos <= ps->size);
CheckCapacity(ps);
int i = 0;
for (i = ps->size; i >=pos; --i)
{
ps->a[i] = ps->a[i - 1];
}
ps->a[pos] = x;
++ps->size;
}
//在顺序表中的某一位置删除数据
void SeqListErase(SeqList* ps,int pos)
{
assert(ps && pos >= 0 && pos < ps->size);
int i = 0;
for (i = pos ; i < ps->size;i++)
{
ps->a[i] = ps->a[i + 1];
}
--ps->size;
}
//在顺序表查找数据
int SeqListFind(SeqList* ps, SLDataType x)
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size; i++)
{
if(ps->a[i]==x)
return i;
}
return -1;
}
测试部分
#include "SeqList.h"
#define _CRT_SECURE_NO_WARNINGS 1
int main()
{
SeqList s;
SeqListInit(&s,3);//顺序表初始化
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPrint(&s);//尾插1至3
SeqListPushFront(&s, -1);
SeqListPushFront(&s, -2);
SeqListPrint(&s);//头插-1、-2
SeqListPopFront(&s);
SeqListPrint(&s);//头删一个
SeqListInsert(&s, 2, 10);
SeqListPrint(&s);//在第三个位置插入10
SeqListErase(&s, 2);
SeqListPrint(&s);//删除第三个位置的数
return 0;
}
//作者定期分享C语言学习路上的经验,欢迎关注哦
标签:ps,顺序,SeqList,干货,表及,源码,SLDataType,void,size 来源: https://blog.csdn.net/Wyf_Fj/article/details/114253123