栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

手撕顺序表(C语言实现)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手撕顺序表(C语言实现)

顺序表本质就是个数组,存放在里面的数据必须是连续的。

话不多说,直接上代码 ,代码注释算是比较详细了。

SeqList.h(顺序表在这里创建 ,声明一下函数。)
#pragma once //防止被重复包含
#include 
#include
#include
#include
#include
#include
typedef int SLDataType;//这样做的好处可以随时更改顺序表的数据类型
//这里的SLDataType就是类型名 现在它就是int

//vector
typedef struct SeqList
{
	SLDataType* a;//顺序表的表长 指向动态开辟的数组
	int size;//有效数据的个数 同时也是最后一个元素的下标
	int capacity;//容量
}SL,SeqList;
void SeqListInit(SL* ps);
void SeqListDestory(SL* ps);
void SeqListPrint(SL* ps);//打印插入的值
void SeqListCheckCapacity(SL *ps);//检查容量
void SeqListPushBack(SL* ps, SLDataType x);//尾部插入
void SeqListPopBack(SL* ps);//尾部删除
void SeqListPushFront(SL* ps, SLDataType x);//头上的插入
void SeqListPopFront(SL* ps);//头上的删除

//中间位置插入和删除
void SeqListInsert(SL* ps, int pos, SLDataType x);//结构体指针 插入的位置 插入的数据
void SeqListErase(SL* ps, int pos);//结构体指针 删除的位置

//顺序表查找
int SeqListFind(SL* ps, SLDataType x);
SeqList.c(声明函数的实现)
//SeqList的实现
void SeqListInit(SL* ps) 
{
	
//初始化顺序表 为其开辟空间
	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//开辟了四个SLDataType大小的空间 
	if (ps->a == NULL)//结构体指针 访问结构体成员用->
	{
		printf("申请内存失败n");
		exit(-1);//直接结束掉程序
	}
	ps->size = 0;
	ps->capacity = 4;
}
//打印顺序表内容
void SeqListPrint(SL* ps) 
{
	int i = 0;
	assert(ps);
	for ( i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("n");
}
//检查空间是否足够 
void SeqListCheckCapacity(SL* ps) 
{
	//如果满了需要增容  一般增加到原来的二倍 增的少 增加频繁 增的多 浪费空间
	if (ps->size >= ps->capacity)//如果数组个数大于等于数组容量 说明数组满了
	{
		ps->capacity *= 2;
		ps->a = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity);//realloc 参数1 原来的空间 参数2 你要的新空间
		if (ps->a == NULL)//如果数组为空
		{
			printf("扩容失败n");
			exit(-1);//直接干掉程序 这句话太粗暴 就像生病了直接抢救都不抢救直接埋了
		}
	}
	//如果后面有足够的空间 原地增容,若后面没有足够的空间 找一块新的空间把数据拷过去,再释放掉旧的空间
}
//销毁顺序表
void SeqListDestory(SL* ps)
{
	free(ps->a);//把指针所指向的空间释放
	ps->a = NULL;//把指针变为空指针
	ps->size = ps->capacity = 0;//再把其他数据都变为0
}
//尾部插入
void SeqListPushBack(SL* ps, SLDataType x) 
{
	
	SeqListInsert(ps, ps->size, x);
}

//尾部删除
void SeqListPopBack(SL* ps) 
{
	assert(ps);
	//ps->a[ps->size - 1] = 0; 你的电脑删除某个软件 是因为只是把文件系统的链接删除了 真实文件没有删 直到这些文件的空间被其他文件覆盖 才会完全消息
	//所以上面这行代码不需要 万一那个地方本来就是0呢
	ps->size--;
}
//头部插入 //插入的时候一定要注意size是否超过了Capacity 
void SeqListPushFront(SL* ps, SLDataType x)//头上的插入 //没有接口可以直接在数据前方增加空间 只能先把要插入位置的数据往后挪
{
	
	SeqListInsert(ps, 0, x);
}
//头上的删除
void SeqListPopFront(SL* ps) 
{
	assert(ps);
	int start = 0;
	while (start<= ps->size-2)//最后一个元素是size-1 而start是把后面的元素往前面挪 所以start的最后一个位置是size-2
	{
		ps->a[start] = ps->a[start + 1];//从后往前挪 把第一个元素给覆盖掉 再把最后一个元素给删掉
		++start;
	}
	ps->size--;
}

//中间位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x) //结构体 插入的位置 插入的数据
{
	assert(ps);
	assert(pos <= ps->size && pos >= 0);//这个地方小于等于ps->size 上面的尾插就可以不写了 直接调用
	SeqListCheckCapacity(ps);//调用扩容(检查 )函数
	int middleInsert = ps->size - 1;//middleInsert是最后一个元素的位置
	while (middleInsert >= pos)//如果middleInsert的位置在pos的位置后面
	{
		ps->a[middleInsert + 1] = ps->a[middleInsert];//将pos要插入的位置后面的元素全部向后挪
		--middleInsert;//这里写成++ 写成个死循环了..
	}
	ps->a[pos] = x;//数据放进去
	ps->size++;//元素个数加1
}

//中间位置删除
void SeqListErase(SL* ps, int pos) //结构体 删除的位置
{
	assert(ps);
	int middleDel = pos;//middleDel是pos的右边
	while (middleDel < ps->size -1)//停止结果 小于等于最后一个位置
	{
		ps->a[middleDel] = ps->a[middleDel+1];//将pos的位置挪到最后 然后删除
		++middleDel;
	}
	ps->size--;
}
//查找
int SeqListFind(SL* ps, SLDataType x) //找到后 返回该元素的下标
{
	assert(ps);
	int i = 0;
	while (i < ps->size)
	{
		if (ps->a[i] == x)
		{
			return i;//找到返回i
		}
		++i;
	}
	//找不到
	return -1;
}
test.c(测试顺序表)
//最好写一个接口测试一个接口 如果一起测,错误了不知道哪个借口有错误!!!

//顺序表
//测试头尾插入删除
void TestSeqList1() 
{
	//尾部插入测试
	SeqList s;
	SeqListInit(&s);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);//从这里开始已经发生越界了
	SeqListPushBack(&s, 6);//越界就像查酒驾 必须在那个点被逮住了 才会报错 也就是说越界编辑器可能不报错
	SeqListPushBack(&s, 7);//最后size为7 capacity为4 你4个空间现在有7个元素 
	SeqListPushBack(&s, 8);//扩容过了就没事了
	SeqListPushBack(&s, 9);
	SeqListPrint(&s);
	
	//尾部删除测试
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPrint(&s);

	//头部插入测试
	SeqListPushFront(&s, -1);//插入-1
	SeqListPushFront(&s, -2);
	SeqListPushFront(&s, -3);

	SeqListPrint(&s);
	
	//头部删除测试
	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPrint(&s);

	//中间插入
	SeqListInsert(&s, 4, 5);//在下标为4的地方插入 一个元素5
	SeqListPrint(&s);

	//中间删除
	SeqListErase(&s, 5);//删除下标是五的元素 也就是第六个元素
	SeqListPrint(&s);

	
	int pos = SeqListFind(&s, 5);//找到5这个元素的下标 赋给pos
	if (pos != -1)
	{
		SeqListErase(&s, pos);//根据下标删除5这个元素
	}
	SeqListPrint(&s);
	SeqListDestory(&s);
}
int main() 
{
	TestSeqList1();
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/429793.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号