1.顺序表与数组的区别
1.顺序表底层为数组,对数组进行封装,实现了常用的增删查改等接口,就实现了顺序表。
2.顺序表分类:
1.静态顺序表
1.1静态顺序表:
//静态顺序表//
#define N 100;
typedef int SepDataList;//对int 重定义//
typedef struct SepList {
SepDataList arr[100];//静态数组空间//
int size;//有效数据个数//
}SL;
1.2 缺点:
1.给定空间为有限大小,无法开辟新空间。
2.空间给小不够用,给大容易造成空间浪费。
2.动态顺序表
2.1动态顺序表(按需申请)
typedef int SepDataList;
typedef struct SepList {
SepDataList* arr;//底层结构为数组
int capacity;//空间容量//
int size;//有效数据个数//
}SL;
动态顺序表可以动态开辟空间,我们在利用时就可以按需索取,基本不会出现开辟空间不够用情况。
3.动态顺序表的实现。
3.1创建动态顺序表
3.2初始化
函数接口: SLInit(&s1)
//初始化//
void SLInit(SL* ps) {
ps->arr = NULL;
ps->capacity = ps->size = 0;
}
3.3开辟空间
函数接口:SLChangespace(&s1)
void SLChangespace(SL*ps) {
if (ps->size == ps->capacity) {//当有效数据与空间大小对等时进行开辟//
//以二倍初始空间进行增大空间//
SepDataList newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//判断是否为第一次开辟(4)//
SepDataList* tem = (SepDataList*)realloc(ps->arr, newcapacity * sizeof(SepDataList));
//判断是否开辟成功//
if (tem == NULL) {
perror("space fail!");
exit(1);
}
//开辟成功//
ps->capacity = newcapacity;//新空间大小//
ps->arr = tem;//新空间起始地址//
}
}
3.4 插入数据
3.4.1 尾部插入
函数接口:SLpushback(&s1,x)
//尾插//
void SLpushback(SL* ps,SepDataList x) {
assert(ps);
SLChangespace(ps);//判断是否需要扩容//
//空间足够直接插入//
ps->arr[ps->size++] = x;
}
3.4.2 头部插入
函数接口:SLpushhead(&s1,x)
//头插//
void SLpushhead(SL* ps, SepDataList x) {
assert(ps);
SLChangespace(ps);//空间判断//
for (int i = ps->size; i > 0; --i) {
ps->arr[i] = ps->arr[i-1];//数据后移,空出头部//
}
ps->arr[0] = x;
ps->size++;//有效数据加一//
}
3.4.3 任意位置插入
函数接口:SLpushappoint(&s1, pos, x)
//任意位置插入//
void SLpushappoint(SL* ps, int pos, SepDataList x) {
//pos 代表指定位置,x 为要插入的数据//
assert(ps);
assert(pos >= 0 && pos <= ps->size);
for (int i = ps->size; i > pos; i--) {
ps->arr[i] = ps->arr[i-1];
}
ps->arr[pos] = x;
ps->size++;
}
3.5 删除数据
3.5.1 尾部删除
函数接口:SLpopback(&s1,x)
//尾删//
void SLpopback(SL*ps) {
assert(ps);
ps->size--;//将有效数据末位置前移//
}
3.5.2 头部删除
函数接口:SLpophead(&s1,x)
//头删//
void SLpophead(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--;
}
3.5.3任意位置删除
函数接口:SLpopappoint(&s1, pos)
//任意位置删除//
void SLpopappoint(SL* ps, int pos) {
assert(ps);
assert(ps->size);
assert(pos >= 0 && pos < ps->size);
for (int i = pos; i <ps->size-1 ; i++) {
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
3.6查找数据
函数接口:SLFind(&s1,x);
1.定义判断条件(假定返回所在数组位置下标,不存在返回-1)
int n = SLfind(&s1, x);
if (n>=0) {
printf("在下标为%d处",n);
}
else {
printf("找不到该数据");
}
查找函数如下:
//查找
int SLfind(SL* ps ,SepDataList x) {
assert(ps);
//进行遍历//
for (int i = 0; i < ps->size; i++) {
if (x == ps->arr[i]);
return i;
}
return -1;
}
3.7 打印数据
函数接口:SLprint(&s1);
void SLprint(SL* ps) {
assert(ps);
for (int i = 0; i < ps->size; i++) {
printf("%d ", ps->arr[i]);
}
printf("\n");
}
3.8 销毁动态内存
函数接口:SLDestroy(&s1);
//销毁//
void SLDestroy(SL* ps) {
assert(ps);
if (ps->arr)
//判断是否为空 为空就无需释放//
{
free(ps->arr);
}
ps->arr = NULL;
ps->capacity = ps->size = 0;
}
4 测试文件与头文件
4.1 头文件
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//静态顺序表//
#define N 100;
typedef int SepDataList;//对int 重定义//
typedef struct SepList {
SepDataList arr[100];//静态数组空间//
int size;//有效数据个数//
}SL;
typedef int SepDataList;
typedef struct SepList {
SepDataList* arr;//底层结构为数组
int capacity;//空间容量//
int size;//有效数据个数//
}SL;
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLpushback(SL* ps, SepDataList x);
void SLpushhead(SL* ps, SepDataList x);
void SLpopback(SL* ps);
void SLpophead(SL* ps);
void SLprint(SL* ps);
void SLpopappoint(SL* ps, int pos);
void SLpushappoint(SL* ps, int pos, SepDataList x);
int SLfind(SL* ps, SepDataList x);
4.2 测试文件:
#include"SepList.h"
#define _CRT_SECURE_NO_WARNINGS
int main() {
SepDataList x = 0;
SL s1;
SLInit(&s1);//初始化//
//头插//
SLpushback(&s1, 4);
SLpushback(&s1, 5);
SLpushback(&s1, 6);
SLprint(&s1);
//尾插//
SLpushhead(&s1, 1);
SLpushhead(&s1, 2);
SLpushhead(&s1, 3);
SLpushhead(&s1, 4);
SLprint(&s1);
//尾删//
SLpopback(&s1);
SLpopback(&s1);
SLpopback(&s1);
SLprint(&s1);
//头删//
SLpophead(&s1);
SLprint(&s1);
//任意位置插//
SLpushappoint(&s1, 1, 3);
SLprint(&s1);
//任意位置删//
SLpopappoint(&s1, 3);
SLprint(&s1);
//查找//
printf("请输入您要查询的数字\n");
scanf("%d", &x);
int n = SLfind(&s1, x);
if (n>=0) {
printf("在%d位置处", n);
}
else {
printf("找不到");
}
SLDestroy(&s1);
return 0;
}
一键三连