C语言 动态顺序表

文章介绍了顺序表的概念,包括静态和动态两种形式,并详细阐述了顺序表的接口实现,如初始化、查找、插入、删除、打印和销毁等操作。此外,还讨论了如何在内存中通过数组动态管理顺序表的存储空间,特别是在插入和删除时的扩容机制。
摘要由CSDN通过智能技术生成

 

目录

一,何为顺序表

二,静态与动态之分

三,接口实现

​四,实现细节


一,何为顺序表


顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。

二,静态与动态之分

静态顺序表:使用定长数组存储元素。
动态顺序表:使用动态开辟的数组存储。

三,接口实现

注意:

1,结构体SeqList中的成员有

指向动态开辟的空间的指针

有效数据的个数

储存有效个数的最大值(容量)

2,将int重命名为SLDateType方便顺序表储存其他类型数据,如果下次使用存储float类型的数据,将int换为float即可

3,各个功能的实现就是函数的实现

有增删查改,初始化,打印,销毁

其中增分尾插,头插,pos位置插入,接口实现有重复

删分尾删,头删,pos位置删除,接口实现有重复

#pragma once

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

typedef int SLDateType;

typedef struct SeqList
{
	SLDateType* p;
	int size;		//有效数据个数
	int capacity;	//能存储数据个数
}SL;

//初始化
void SeqListInit(SL* psl);
//查找
int SeqListFind(SL* psl, SLDateType x);
//尾插
void SeqListPushBack(SL* psl, SLDateType x);
//尾删
void SeqListPopBack(SL* psl);
//头插
void SeqListPushFront(SL* psl, SLDateType x);
//头删
void SeqListPopFront(SL* psl);
//在pos位置插入
void SeqListInsert(SL* psl, int pos, SLDateType x);
//在pos位置删除
void SeqListErase(SL* psl, int pos);
//销毁
void SeqListDestory(SL* psl);
//打印
void SeqListPrint(SL* psl);
//扩容
void SeqListChekCapacity(SL* psl);

​四,实现细节

#define _CRT_SECURE_NO_WARNINGS 1

#include "seqlist.h"
//扩容
void SeqListChekCapacity(SL* psl)
{
	//实现插入操作时判断空间是否足够,不够则扩容
	if (psl->size == psl->capacity)
	{
		int NewCapacity = (psl->capacity == 0 ? 4 : (2 * psl->capacity));
		SLDateType* temp = (SLDateType*)realloc(psl->p, sizeof(SL) * NewCapacity);

		if (temp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}

		psl->p = temp;
		psl->capacity = NewCapacity;
	}
}
//在pos位置插入
void SeqListInsert(SL* psl, int pos, SLDateType x)
{
	//空间不足
	SeqListChekCapacity(psl);

	//空间足够
	//考虑pos是否合法
	assert(pos >= 0 && pos <= psl->size);

	int end = psl->size - 1;
	while (end >= pos)
	{
		psl->p[end + 1] = psl->p[end];
		end--;
	}

	psl->p[pos] = x;
	psl->size++;
}
//在pos位置删除
void SeqListErase(SL* psl, int pos)
{
	//判断pos是否合法
	assert(pos >= 0 && pos < psl->size);

	int begin = pos;
	while (begin < psl->size - 1)
	{
		psl->p[begin] = psl->p[begin + 1];
		begin++;
	}

	psl->size--;
}
//尾插
void SeqListPushBack(SL* psl, SLDateType x)
{
	判断空间是否足够,不够则扩容
	//SeqListChekCapacity(psl);

	容量足够
	//psl->p[psl->size] = x;
	//psl->size++;

	//复用SeqListInert()
	SeqListInsert(psl, psl->size, x);
}
//尾删
void SeqListPopBack(SL* psl)
{
	//assert(psl->size > 0);

	//psl->size--;

	//复用SeqListErase()
	SeqListErase(psl, psl->size - 1);
}
//头插
void SeqListPushFront(SL* psl, SLDateType x)
{
	空间不足
	//SeqListChekCapacity(psl);

	空间足够
	//for (int i = psl->size - 1; i >= 0; i--)
	//{
	//	psl->p[i + 1] = psl->p[i];
	//}

	//psl->p[0] = x;
	//psl->size++;

	//复用SeqListInsert()
	SeqListInsert(psl, 0, x);
}
//头删
void SeqListPopFront(SL* psl)
{
	//assert(psl->size > 0);

	//for (int i = 1; i < psl->size; i++)
	//{
	//	psl->p[i - 1] = psl->p[i];
	//}

	//psl->size--;

	//复用SeqListErase()
	SeqListErase(psl, 0);
}
//初始化
void SeqListInit(SL* psl)
{
	psl->p = NULL;
	psl->size = psl->capacity = 0;
}
//打印
void SeqListPrint(SL* psl)
{
	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->p[i]);
	}

	printf("\n");
}
//查找
//找到返回下标,否则返回-1
int SeqListFind(SL* psl, SLDateType x)
{
	for (int i = 0; i < psl->size; i++)
	{
		if (psl->p[i] == x)
		{
			return i;
		}
	}

	return -1;
}
//销毁
void SeqListDestory(SL* psl)
{
	free(psl->p);
	psl->p = NULL;

	psl->size = psl->capacity = 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y雨何时停T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值