顺序表(内含代码和图解)【新手入门必看】
前言
如果在程序中不对数据进行管理,可能会导致数据丢失、操作数据困难、野指针等情况。
通过数据结构,能够有效将数据组织和管理在一起,按照我们的方式对数据进行任意的增删查改等操作。
最基础的数据结构:数组
下面我们也将使用数组的知识对比学习顺序表。
1、线性表和顺序表的介绍
线性表 | 逻辑结构连续、物理结构不一定连续 |
---|---|
顺序表 | 逻辑结构连续、物理结构连续(顺序表是线性表的一种) |
2、顺序表和数组的区别
顺序表的底层逻辑是数组,
顺序表是对数组的封装,实现常用的增删查改等的接口。
3、顺序表的分类
静态顺序表 | 使用定长的数组储存元素(缺点:空间给小了不够用,给大了浪费) |
---|---|
动态顺序表 | 需要按需申请空间 |
3.1 静态顺序表
由于静态顺序表存在空间过大、过小的问题,
所以在使用顺序表的过程中我们会选择使用动态顺序表,
所以这里我们就不再赘述了~
3.2 动态顺序表
3.3 动态顺序表的增删查改
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//动态顺序表
typedef int SLDateType;//将int重命名
//创建顺序表
typedef struct SeqList
{
SLDateType* arr;
int size;//有效的数据个数
int capacity;//空间容量
}sl;
//打印顺序表
void SLPrint(sl* ps);
//初始化顺序表
void Initsl(sl* ps);
//销毁顺序表
void Dissl(sl* ps);
//顺序表的尾插
void SLPushBack(sl* ps,SLDateType x);
//顺序表的头插
void SLPushFront(sl* ps, SLDateType x);
//顺序表的尾删
void SLPopback(sl* ps);
//顺序表的头删
void SLPopFront(sl* ps);
//在指定位置插入
void SLPush(sl* ps, int pos, SLDateType x);
//在指定位置删除
void SLPop(sl* ps, int pos);
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
//初始化顺序表
void Initsl(sl* ps)
{
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
//销毁顺序表
void Dissl(sl* ps)
{
if (ps->arr != NULL)
{
free(ps->arr);
ps->arr = NULL;
}
ps->size = ps->capacity = 0;
}
void App(sl* ps)
{
assert(ps);
//申请空间
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDateType* tmp = (SLDateType*)realloc(ps->arr, newcapacity*sizeof(SLDateType));
if (tmp == NULL)
{
perror(tmp);
exit(1);
}
ps->arr = tmp;
ps->capacity = newcapacity;
}
}
//顺序表的尾插
void SLPushBack(sl* ps, SLDateType x)
{
App(ps);
//尾插x
ps->arr[ps->size++] = x;
}
//顺序表的头插
void SLPushFront(sl* ps, SLDateType x)
{
assert(ps);
//申请空间
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDateType* tmp = (SLDateType*)realloc(ps->arr, newcapacity*sizeof(SLDateType));
if (tmp == NULL)
{
perror(tmp);
exit(1);
}
ps->arr = tmp;
ps->capacity = newcapacity;
}
//尾插
for (int i = ps->size; i>0; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[0] = x;
ps->size++;
}
//打印顺序表
void SLPrint(sl* ps)
{
for (int i = 0; i < ps->size; i++)
{
printf("%d ", ps->arr[i]);
}
printf("\n");
}
//顺序表的尾删
void SLPopback(sl* ps)
{
assert(ps);
assert(ps->size);
ps->size--;
}
//顺序表的头删
void SLPopFront(sl* ps)
{
assert(ps);
assert(ps->size);
for (int i = 0; i<ps->size-1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//在指定位置插入
void SLPush(sl* ps, int pos, SLDateType x)
{
assert(ps);
for (int i = ps->size; i>pos; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[pos] = x;
ps->size++;
}
//在指定位置删除
void SLPop(sl* ps, int pos)
{
assert(ps);
assert(pos >= 0&&pos<ps->size);
for (int i = pos; i<ps->size-1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
最后希望这篇文章对大家有所帮助~~~
有什么问题大家可以评论区讨论哦~
点赞+收藏