顺序表的实现

首先的话是要确定一件事就是顺序表是线性表的一种

是逻辑结构和物理结构都是线性的

逻辑结构就是大脑之中理解时而进行的架构

物理结构就是存储在内存空间之中的结构

分为静态和动态的顺序表

首先是扩容,增容,malloc是申请,calloc是加初始化,realooc是增容

接下来就是属于代码

#pragma once
#include<stdio.h>
#include<stdlib.h>	
#include<assert.h>

#define N 1000
typedef int SLDataType;
////静态顺序表
//typedef struct SeqList {
//	SLDataType arr[N];
//	int size; //有效数据个数
//}SL;

//typedef struct SeqList SL

//动态顺序表
typedef struct SeqList {
	SLDataType* arr;
	int size; //有效数据个数
	int capacity; //容量大小
}SL;

void SLPrint(SL* ps);
//初始化
void SLInit(SL* ps);
//销毁
void SLDesTroy(SL* ps);

//尾插
void SLPushBack(SL* ps, SLDataType x);
//头插
void SLPushFront(SL* ps, SLDataType x);

//尾删
void SLPopBack(SL* ps);
//头删
void SLPopFront(SL* ps);

int SLFind(SL* ps, SLDataType x);

//指定位置之前插⼊数据
void SLInsert(SL* ps, int pos, SLDataType x);
//删除指定位置的数据
void SLErase(SL* ps, int pos);

首先先是头文件,头文件就是目录,方便之后进行更改

顺序表要知道大小(有效数据个数)和数据存储,

同时为了方便之后进行更改,那么就是将数据类型进行一个更改

同时为了方便之后去写,那么就是将seqlist重命名为SL

正常情况肯定是动态顺序表好用,静态不知道是否够用且空间浪费不可控

那么就是为了方便跟新,就是需要加一个代码方便更新

void SLcheckCapacity(SL* ps)
{
	//空间不够,申请空间
	if (ps->size == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//三目表达式
		//空间不够-2倍增容
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}

这个是之后都需要判定的

realloc是属于要增加一个数据

正常情况肯定是需要增加两倍

是为了方便空间不浪费太多,也是为了没有频繁的调用而浪费时间

三目操作符就是表达是否是零

接下蓝就是realloc,前面是类型,后面是首地址还有要增加的大小

之后将数据进行一个改变

一个是首地址(realloc是如果原地址不够就会换一个足够的)

一个是容量,同时判断以下有没有增容失败

perror退出加爆出括号里面的内容

首先的话是需要初始化

void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

这个就是将空间的内容为空,同时将长度设置为零

同时还有容量,这个就是设置为零

这里传输的话肯定是需要改变的,因为要更改的话那么就是需要为实参

(.是值,->是地址,),这里完全不需要拷贝的,直接就是可以的

接下来就是属于销毁了

void SLDesTroy(SL* ps)
{
	if(ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

接下来是要插入数据

首先是尾插,插入最后一个合法的数据

void SLPushBack(SL* ps, SLDataType x)
{
	////温柔的处理方式
	//if (ps == NULL)
	//{
	//	return;
	//}
	//粗暴---断言
	//为真-通过,为假-报错
	assert(ps != NULL);

	SLcheckCapacity(ps);
	
	ps->arr[ps->size++] = x;
}

相当的简单

size每次++,基本上都是属于可以让size都处于有效的数组的后面的一个位置

接下就是属于头插

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);         //等价于assert(ps != NULL)
	SLcheckCapacity(ps);
	//直接头插
	//数据整体向后挪动一位
	for (int i = ps->size; i > 0 ;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	++ps->size;
}

首先是确定代码不是空的,同时判断大小够不够

接下蓝需要整体往后挪一位

之后将第一个位设置为相应的数据

接下来就是属于增加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 && ps->size);

	--ps->size;
}
//头删
void SLPopFront(SL* ps)
{
	assert(ps && ps->size);

	for (int i = 0; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}

	--ps->size;
}

之后是查找

//查找x,查找到了就返回对应数据下标
int SLFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			//找到了,返回下标
			return i;
		}
	}
	//没找到,返回无效下标
	return -1;
}

指定位置插入删除

//指定位置之前插⼊数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	//前=:头插
	//后=:尾插
	assert(pos >= 0 && pos <= ps->size);
	SLcheckCapacity(ps);
	for (int i = ps->size; i > pos ;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	++ps->size;
}


//删除指定位置的数据
void SLErase(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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值