本文介绍: 静态顺序表只适合确定需要存储多少数据场景,如果存储数据量不确定的话,空间开太大浪费,开太小不够用。一般都会去使用动态顺序表,根据情况分配多大的空间顺序表是用一段物理地址连续的存储单元存储元素线性结构,一般采用数组进行存储。和尾插一样,要考虑是否空间,但是与尾插不同的地方在于,需要挪动数据进行插入。1.存储空间地址需要一段空间来维护顺序表,需要知道顺序表的起始地址。头删和尾删一样,先判空。有了在指定位置插入删除前提下,头插,头删,尾插,尾删新写法。2.顺序表的元素个数记录顺序表的元素个数

线性表

线性表定义

image.png

image.png

线性表分类

image.png

顺序表

顺序表是用一段物理地址连续的存储单元存储元素的线性结构,一般采用数组进行存储。在数组上完成数据元素增删查改
顺序表一般分为:

静态顺序表只适合确定需要存储多少数据场景,如果存储数据量不确定的话,空间开太大浪费,开太小不够用。一般都会去使用动态顺序表,根据情况分配多大的空间。下面将介绍动态顺序表

顺次表的存储结构

图示
image.png

typedef int ElemType;
typedef struct SeqList
{
	ElemType* a;
	int size;
	int capacity;
}SeqList;

定义一个动态顺序表需要三个属性
1.存储空间的地址需要一段空间来维护顺序表,需要知道顺序表的起始地址
2.顺序表的元素个数记录顺序表的元素个数
3.顺序表的空间容量,用来分配空间

实现顺序表的主要接口函数

//顺序表初始化
void SeqListInit(SeqList* ps);
//顺序表尾插
void SeqListPushBack(SeqList* ps, ElemType x);
//检查容量
void CheckCapicity(SeqList* ps);
//顺序表尾删
void SeqListPopBack(SeqList* ps);
//顺序表头
void SeqListPushFront(SeqList* ps, ElemType x);
//顺序表头
void SeqListPopFront(SeqList* ps);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, ElemType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
//打印顺序表
void SeqListprintf(SeqList* ps);
//销毁顺序表
void DestroyedSeqList(SeqList* ps);

初始化顺序表

这里先为顺序表申请了2个元素类型的空间大小

void SeqListInit(SeqList* ps)
{
	ps->a = (ElemType*)malloc(sizeof(ElemType)*2);
	ps->size = 0;
	ps->capacity = 2;
}

顺序表尾插

在尾部插入的时候要考虑两种情况,分别是

image.png

  • 顺序表未满尾插:直接将元素放入尾部即可

image.png

image.png
代码实现

void SeqListPushBack(SeqList* ps, ElemType x)
{
	assert(ps);
	//检查容量
	CheckCapicity(ps);
	//尾插
	ps->a[ps->size] = x;
	ps->size++;
}

这里检查容量封装一个函数,方便后面插入检查继续复用

void CheckCapicity(SeqList* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity * 2;
		ElemType* tmp = (ElemType*)realloc(ps->a,sizeof(ElemType)*newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

顺序表尾删

在尾删时,也应该考虑两种情况,分别是

image.png
-顺序表已空时,无需删除
-顺序表未空,直接删除尾部元素即可

image.png

代码实现:
这里提供两种写法,一种是暴力检查程序直接崩溃,一种是防止越界程序可以正常运行

void SeqListPopBack(SeqList* ps)
{
	//判空
	assert(ps->size > 0);//如果尾删空顺序表,程序直接崩溃
	//删除
	--(ps->size);
}

image.png

  • 防止越界版
void SeqListPopBack(SeqList* ps)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//删除
	--(ps->size);
}

顺序表头

和尾插一样,要考虑是否有空间,但是与尾插不同的地方在于,需要挪动数据进行插入
图解

image.png
代码实现

void SeqListPushFront(SeqList* ps, ElemType x)
{
	//检查容量
	CheckCapicity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//插入
	ps->a[0] = x;
	++ps->size;
}

顺序表头

头删和尾删一样,先判空。与尾删不一样的地方在于删完后需要挪动数据
图解

image.png
代码实现

void SeqListPopFront(SeqList* ps)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//挪动数据覆盖删除
	int start = 0;
	while (start <= ps->size) 
	{
		ps->a[start] = ps->a[start + 1];
		start++;
	}
	--ps->size;
}

指定位置插入数据

和头插的思想基本一样
图解

image.png
代码实现

void SeqListInsert(SeqList* ps, int pos, ElemType x)
{
	//检查容量
	CheckCapicity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//插入
	ps->a[pos] = x;
	++ps->size;
}

在指定的位置删除数据

思想与头删基本一样
图解

image.png
代码实现

void SeqListErase(SeqList* ps, int pos)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//挪动数据覆盖删除
	while (pos <= ps->size)
	{
		ps->a[pos] = ps->a[pos + 1];
		pos++;
	}
	--ps->size;
}

有了在指定位置插入和删除前提下,头插,头删,尾插,尾删新写法

头插,头删,尾插,尾删新写法

//头插
void SeqListPushFront(SeqList* ps, ElemType x)
{
	SeqListInsert(ps, 0, x);
}
//头删
void SeqListPopFront(SeqList* ps)
{
	SeqListErase(ps, 0);
}
//尾插
void SeqListPushBack(SeqList* ps, ElemType x)
{
	SeqListInsert(ps, ps->size,x);
}
//尾删
void SeqListPopBack(SeqList* ps)
{
	SeqListErase(ps, ps->size);
}

打印顺序表

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

销毁顺序表

动态开辟的内存需要我们主动去释放空间 这里需要主动free

void DestroyedSeqList(SeqList* ps)
{
	free(ps->a);
	ps->a == NULL;
	ps->capacity = ps->size = 0;
}

原文地址:https://blog.csdn.net/FBI_BAIGOU/article/details/134655391

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_20924.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注