纯c实现顺序表 数据结构大全

发布时间:2024年01月16日

????????我们已经知道数组是连续的内存地址,顺序表是由数组为基础的一种数据结构,拥有比数组更多的功能,在概念上属于线性结构,跟链表不同的是,顺序表在物理结构上也是线性的

????????什么是数据结构? 当我们想要使??量使?同?类型的数据时,通过手动定义?量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将?量的数据组织在?起,结构也可以理解为组织数据的方式。

? ? ? ? 数组就是一种最为简单的数据结构,但是数组有着其局限性。

????????求数组的?度,求数组的有效数据个数,随意变化数组的大小,向下标为数据有效个数的位置插?数据。假设数据量?常庞?,频繁的获取数组有效数据个数会影响程序执?效率。结论:最基础的数据结构能够提供的操作已经不能完全满?复杂算法实现。

? ? ? ??

? ? ? ? 接着我带大家,来实现一个这样的数据结构,体会其特点

? ? ? ? 我们先要定义一个结构体来存储数据,这里我们先默认存的数据是整形,(这个不同的需求很容易修改存储的数据类型),我们在这里定义名字为sl简化后面的代码

定义

struct dplist//动态 更常用
{
	int* a;
	int size;//有效数据个数;
	int capa;//顺序表当前大小
}sl;

初始化?

?然后是顺序表的初始化,正常操作

void begin(struct dplist* sl)//初始化
{
	sl->a = NULL;
	sl-> size = 0;
	sl-> capa = 0;
}

定义?

这里是定义,调用前面的begin函数

void sltest()//定义
{
	struct dplist sl;
	begin(&sl);
}

开辟内存?

然后是重要的检查空间跟有效数据个数,以此判断空间是否足够,是不是要多开辟的函数,后面的接口也会大量用到这个

这里采用的是两倍两倍的开辟新内存空间的方法

void checkcapa(struct dplist* sl)//检查空间是否足够 不够的话自动扩容
{
	if (sl->size == sl->capa)
	{
		int newcapa = sl->capa == 0 ? 4 : 2 * sl->capa;
		struct dplist* tmp = (struct dplist*)realloc(sl->a, newcapa * sizeof(struct dplist));
		if (tmp == NULL)
		{
			perror("fall");
			return ;
		}
		sl->a = tmp;
		sl->capa = newcapa;//因为本来sl->capa为0,所以定义newcapa
	}
}

销毁?

然后是数据结构经典的销毁函数,避免内存泄漏

void destroy(struct dplist* sl) //销毁空间,不要浪费
{
	if (sl->a)
		free(sl->a);
	sl->a = NULL;
	sl->capa = 0;
	sl->size = 0;
}

尾插?

然后是简单的尾插函数,记得把有效数据个数的size++

void pushback(struct dplist* sl,int x)//尾插
{
	//assert(sl)
	if (sl == NULL)//比assert柔和的方式
	{
		return;
	}

	//判断空间
	checkcapa(sl);//sl已经是指针了,直接传
	//插入数据 注意size的指向 要指向下一个,因为后面还要插
	sl->a[sl->size] = x;
	sl->size++;
}

头插?

然后是头插,把所有数据都向后移一位

void pushfront(struct dplist* sl,int x)//头插 历史数据后移
{
	if (sl == NULL)
	{
		return;
	}

	//判断空间
	checkcapa(sl);//直接调用函数

	//后移历史数据
	for (int i = sl->size; i > 0; i--)
	{
		sl->a[i] = sl->a[i - 1];
	}
	//头插
	sl->a[0] = x;
	sl->size++;
}

尾删?

然后是尾删接口,直接size--就可以,因为下一次size++的时候这个位置会赋值新的数了

void popback(struct dplist* sl)//尾删
{
	if (sl == NULL)
	{
		return;
	}

	//判断是否已经为空
	if (sl->size == 0)
	{
		return;
	}
	sl->size--;//在size的数据如果下次size到这里就会覆盖掉
}

头删?

然后是头删,数据集体向前移动来覆盖

void popfront(struct dplist* sl)//头删 数据直接向左移动来覆盖
{
	if (sl == NULL)
	{
		return;
	}

	//判断是否已经为空
	if (sl->size == 0)
	{
		return;
	}

	//向左移动
	for (int i = 0; i < sl->size ; i++)
	{
		sl->a[i] = sl->a[i + 1];
	}
}

?指定位置插入数据

然后是指定位置插入数据

一样是把指定的位置后面的数据向后移动就可以了

void slinsert(struct dplist* sl, int pos, int x)//指定位置插入数据 pos为下标
{
	if (sl == NULL)
	{
		return;
	}
	checkcapa(sl);

	//把pos及后面的数据向后挪
	for (int i = sl->size; i > pos; i--)
	{
		sl->a[i] = sl->a[i - 1];
	}

	//对pos加以限制,避免程序崩溃
	if (pos < 0 || pos > sl->size)
	{
		return;
	}
	//注意size的值 因为又插入了值
	sl->a[pos] = x;
	sl->size++;
}

?指定位置删除数据

与指定位置插入数据相对应的就是指定位置删除数据,让其后面的数据向前移动覆盖就可以了

void sldelete(struct dplist* sl, int pos)//指定位置删除数据 也是覆盖 往前移动
{
	//经典判断
	if (sl == NULL)
	{
		return;
	}

	//判断是否已经为空
	if (sl->size == 0)
	{
		return;
	}

	//对pos加以限制,避免程序崩溃
	if (pos < 0 || pos >= sl->size)
	{
		return;
	}

	//往前覆盖
	for (int i = pos; i < sl->size - 1; i++)
	{
		sl->a[i] = sl->a[i + 1];
	}

	sl->size--;//数据减少
}

?查找数据是否存在

然后是查找数据是否存在,简单遍历就可以了

int slfind(struct dplist* sl,int x)//查找数据是否存在 存在返回1 否则-1
{
	// 经典判断
	if (sl == NULL)
	{
		return;
	}

	for (int i = 0; i < sl->size; i++)
	{
		if (sl->a[i] == x)
		{
			return 1;
		}
	}
	return -1;
}

打印顺序表?

然后是打印函数,可以检查前面的操作正不正确

void slprint(struct dplist* sl)//打印顺序表 看操作是否正确
{
	for (int i = 0; i < sl->size; i++)
	{
		printf("%d ", sl->a[i]);
	}
	printf("\n");
}

最后给出完整代码

#define _CRT_SECURE_NO_WARNINGS

//顺序表  静态和动态
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "sep.h"

struct seplist//静态
{
	int aa[100];
	int size;//有效数据个数
};

struct dplist//动态 更常用
{
	int* a;
	int size;//有效数据个数;
	int capa;//顺序表当前大小
}sl;

void begin(struct dplist* sl)//初始化
{
	sl->a = NULL;
	sl-> size = 0;
	sl-> capa = 0;
}
void sltest()//定义
{
	struct dplist sl;
	begin(&sl);
}
void destroy(struct dplist* sl) //销毁空间,不要浪费
{
	if (sl->a)
		free(sl->a);
	sl->a = NULL;
	sl->capa = 0;
	sl->size = 0;
}
void checkcapa(struct dplist* sl)//检查空间是否足够 不够的话自动扩容
{
	if (sl->size == sl->capa)
	{
		int newcapa = sl->capa == 0 ? 4 : 2 * sl->capa;
		struct dplist* tmp = (struct dplist*)realloc(sl->a, newcapa * sizeof(struct dplist));
		if (tmp == NULL)
		{
			perror("fall");
			return ;
		}
		sl->a = tmp;
		sl->capa = newcapa;//因为本来sl->capa为0,所以定义newcapa
	}
}
void pushback(struct dplist* sl,int x)//尾插
{
	//assert(sl)
	if (sl == NULL)//比assert柔和的方式
	{
		return;
	}

	//判断空间
	checkcapa(sl);//sl已经是指针了,直接传
	//插入数据 注意size的指向 要指向下一个,因为后面还要插
	sl->a[sl->size] = x;
	sl->size++;
}
void pushfront(struct dplist* sl,int x)//头插 历史数据后移
{
	if (sl == NULL)
	{
		return;
	}

	//判断空间
	checkcapa(sl);//直接调用函数

	//后移历史数据
	for (int i = sl->size; i > 0; i--)
	{
		sl->a[i] = sl->a[i - 1];
	}
	//头插
	sl->a[0] = x;
	sl->size++;
}
void popback(struct dplist* sl)//尾删
{
	if (sl == NULL)
	{
		return;
	}

	//判断是否已经为空
	if (sl->size == 0)
	{
		return;
	}
	sl->size--;//在size的数据如果下次size到这里就会覆盖掉
}
void popfront(struct dplist* sl)//头删 数据直接向左移动来覆盖
{
	if (sl == NULL)
	{
		return;
	}

	//判断是否已经为空
	if (sl->size == 0)
	{
		return;
	}

	//向左移动
	for (int i = 0; i < sl->size ; i++)
	{
		sl->a[i] = sl->a[i + 1];
	}
}
void slinsert(struct dplist* sl, int pos, int x)//指定位置插入数据 pos为下标
{
	if (sl == NULL)
	{
		return;
	}
	checkcapa(sl);

	//把pos及后面的数据向后挪
	for (int i = sl->size; i > pos; i--)
	{
		sl->a[i] = sl->a[i - 1];
	}

	//对pos加以限制,避免程序崩溃
	if (pos < 0 || pos > sl->size)
	{
		return;
	}
	//注意size的值 因为又插入了值
	sl->a[pos] = x;
	sl->size++;
}
void sldelete(struct dplist* sl, int pos)//指定位置删除数据 也是覆盖 往前移动
{
	//经典判断
	if (sl == NULL)
	{
		return;
	}

	//判断是否已经为空
	if (sl->size == 0)
	{
		return;
	}

	//对pos加以限制,避免程序崩溃
	if (pos < 0 || pos >= sl->size)
	{
		return;
	}

	//往前覆盖
	for (int i = pos; i < sl->size - 1; i++)
	{
		sl->a[i] = sl->a[i + 1];
	}

	sl->size--;//数据减少
}
int slfind(struct dplist* sl,int x)//查找数据是否存在 存在返回1 否则-1
{
	// 经典判断
	if (sl == NULL)
	{
		return;
	}

	for (int i = 0; i < sl->size; i++)
	{
		if (sl->a[i] == x)
		{
			return 1;
		}
	}
	return -1;
}
void slprint(struct dplist* sl)//打印顺序表 看操作是否正确
{
	for (int i = 0; i < sl->size; i++)
	{
		printf("%d ", sl->a[i]);
	}
	printf("\n");
}
int main()
{

	return 0;
}

文章来源:https://blog.csdn.net/2302_79128004/article/details/135578609
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。