2024年【数据结构与算法】顺序表_数据机构顺序表的算法,2024年最新C C++开发需要学什么

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

这一步我们需要创建顺序表并对其进行初始化,
将其 size 置零,capaticy 置为传入参数。
如果想把顺序表中每个数据都初始化为 0 的话可以使用 calloc 函数。

//初始化顺序表
void SeqListInit(SeqList\* ps, size\_t capacity);

void SeqListInit(SeqList\* ps, size\_t capacity)
{
	ps->data = (SLDataType\*)malloc(sizeof(SLDataType) \* capacity);
	if (ps->data == NULL)
	{
		perror("SeqListInit");
		return;
	}
	ps->size = 0;
	ps->capacity = capacity;
}


顺序表打印

打印顺序表中的数据,
因为顺序表中只有 size 个数据,
所以只需要循环 size 次打印。

void SeqListPrint(SeqList\* ps);

void SeqListPrint(SeqList\* ps)
{
	assert(ps->size > 0);
	for (int i = 0; i < ps->size; i++)
		printf("%d ", ps->data[i]);
	printf("\n");
}


检查空间,如果满了,进行增容

后面无论是要尾插、头插还是中间插,
都有可能出现顺序表满的情况,
所以在此之前要进行空间检查,
如果空间存满了就需要扩容。
这里每次将容量扩大为原来的 2 倍,
需要使用 realloc 函数。
扩容之后不要忘了重置 capacity

void CheckCapacity(SeqList\* ps);

void CheckCapacity(SeqList\* ps)
{
	SLDataType\* tmp = NULL;
	if (ps->capacity == ps->size)
		tmp = realloc(ps->data, ps->capacity \* 2);
	if (tmp != NULL)
		ps->data = tmp;
	else
		return;
	ps->capacity \*= 2;
}


顺序表尾插

插入数据之前先判断是否需要扩容。
在顺序表的最后插入一个数据 x
由于 size 的值就是现有数据中最后一个数据的下标 +1
所以直接给 size 位置处的数据赋值。
尾插之后记得 size++

void SeqListPushBack(SeqList\* ps, SLDataType x);

void SeqListPushBack(SeqList\* ps, SLDataType x)
{
	CheckCapacity(ps);
	ps->data[ps->size] = x;
	ps->size++;
}


顺序表尾删

尾删,并不需要我们操作现有的最后一个数据。
因为我们看到的数据是前 size 个,
所以只需要改变 size 就可以减少呈现在我们眼前的数据。

void SeqListPopBack(SeqList\* ps);

void SeqListPopBack(SeqList\* ps)
{
	assert(ps->size > 0);
	ps->size--;
}


顺序表头插

插入数据之前先判断是否需要扩容。
头插的话后面的数据就要往后移,
从后往前来即可:
在这里插入图片描述
然后将空出的位置赋成我们想要的 x 即可。
最后将 size++

void SeqListPushFront(SeqList\* ps, SLDataType x);

void SeqListPushFront(SeqList\* ps, SLDataType x)
{
	CheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->data[end + 1] = ps->data[end];
		end--;
	}
	ps->data[0] = x;
	ps->size++;
}


顺序表头删

头删只需要把头上的元素覆盖掉,
覆盖顺序如下:
在这里插入图片描述
最后别忘了 size–

void SeqListPopFront(SeqList\* ps);

void SeqListPopFront(SeqList\* ps)
{
	assert(ps->size > 0);
	int start = 1;
	while (start < ps->size)
	{
		ps->data[start - 1] = ps->data[start];
		start++;
	}
	ps->size--;
}


顺序表查找

我们还需要实现在指定位置处插入或删除元素,
这就需要知道指定位置是哪个位置,
所以在此之前先完成查找接口。
只需遍历一遍顺序表,
这里返回的是指定元素第一次出现的位置。

int SeqListFind(SeqList\* ps, SLDataType x);

int SeqListFind(SeqList\* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; ++i)
		if (ps->data[i] == x)
			return i;
	return -1;
}


删除指定位置的值

删除指定位置的值,
只需要将指定位置处的数据覆盖掉。
覆盖方式为从前往后走:
在这里插入图片描述

最后记得 size–

void SeqListErase(SeqList\* ps, size\_t pos);

void SeqListErase(SeqList\* ps, size\_t pos)
{
	assert(pos < ps->size);
	int start = pos + 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		start++;
	}
	ps->size--;
}


在指定位置插入

插入数据还是要先判断是否需要扩容。
首先将 pos 处及其后部元素向后挪一位,
然后把 pos 处元素赋成 x
在这里插入图片描述

void SeqListInsert(SeqList\* ps, size\_t pos, SLDataType x)
{
	assert(pos <= ps->size);
	SeqListCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;
}


顺序表销毁

由于顺序表是动态开辟来的,
所以程序结束时一定要将空间释放,
以免造成内存泄漏。

void SeqListDestory(SeqList\* ps);

void SeqListDestory(SeqList\* ps)
{
	free(ps->data);
	ps->data = NULL;
	ps->capacity = 0;
	ps->size = 0;
}


总结

对于顺序表,很明显它是连续存放数据的,且支持随机访问,可以直接访问任意位置处的数据。

但是,每次头插或指定位置插入、删除元素都需要遍历数组,时间复杂度为 O(N),效率较低。

此外,这里动态增容一次增加原来的一倍,当数据量很大的时候,增容占用的空间也会更多,而如果剩余数据很少,那同样会造成大量空间的浪费。


完整代码
SeqList.h

将有关变量、符号及函数的声明、头文件的引用放在头文件中:

#pragma once

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

typedef int SLDataType;

typedef struct SeqList
{
	SLDataType\* data;
	int size;
	int capacity;
}SeqList;

//初始化顺序表
void SeqListInit(SeqList\* ps, size\_t capacity);

// 顺序表打印
void SeqListPrint(SeqList\* ps);

// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList\* ps);



![img](https://img-blog.csdnimg.cn/img_convert/821a4f4a30baa817178cd3e00b014214.png)
![img](https://img-blog.csdnimg.cn/img_convert/2d17db1b77ec77074bb4491185d102d1.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

rint(SeqList\* ps);

// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList\* ps);



[外链图片转存中...(img-CtQB2lRi-1715591696309)]
[外链图片转存中...(img-ChDg04EK-1715591696310)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值