顺序表的动态实现

本文档展示了如何使用C语言实现动态顺序表,包括初始化、销毁、插入、删除、查找等操作,并提供了详细的测试用例,涵盖了顺序表的基本功能。核心功能通过realloc函数实现动态内存分配,确保数据结构的灵活性。
摘要由CSDN通过智能技术生成

数据结构顺序表的动态实现,作为学习过程的记录

顺序表要求所存数据在逻辑上和物理上均是连续存放,因此顺序表采用数组形式存放数据,主要使用realloc函数来为顺序表动态分配存储空间。

编译器环境

visual studio 2022 

项目结构

 SqList.h

结构定义及接口函数

#pragma once
#include<stdio.h>
#include<stdlib.h>
//#define N 1000
//
静态顺序表
//typedef int SLDataType;
//
//typedef struct SqList
//{
//	SLDataType data[N];
//	int size; //表示数组中存储了多少个元素
//}SL;
//
//void SqListInit(SL* ps);
静态特点:如果满了就不让插入
N给小了不够用,N给大了浪费空间
//void SqListPushBack(SL* ps, SLDataType x);
//void SqListPopBack(SL* ps);
//void SqListPushFront(SL* ps, SLDataType x);
//void SqListPopFront(SL* ps);



//动态顺序表
typedef int SLDataType;

typedef struct SqList
{
	SLDataType* data;
	int size; //表示数组中存储了多少个元素
	int capacity;//表示数组实际容量
}SL;

void SqListPrint(SL* ps);
void SqListInit(SL* ps);
void SqListDestroy(SL* ps);

void SqListCheckCapacity(SL* ps);
void SqListPushBack(SL* ps, SLDataType x);
void SqListPopBack(SL* ps);

void SqListPushFront(SL* ps, SLDataType x);
void SqListPopFront(SL* ps);

//查找某个值的下标,没有找到返回-1
int SqListFind(SL* ps, SLDataType x);

//在指定pos下标位置插入x
void SqListInsert(SL* ps, int pos, SLDataType x);

//删除在pos下标处的数据
void SqListErase(SL* ps, int pos);

SqList.c 接口函数的具体实现

#pragma once
#include "SqList.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

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

void SqListInit(SL* ps)
{
	ps->data = NULL;
	ps->size = ps->capacity = 0;
}

void SqListDestroy(SL* ps)
{
	free(ps->data); //free()只将指针指向的空间还给系统
	ps->data = NULL;
	ps->size = ps->capacity = 0;
}

void SqListCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->data, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}

		ps->data = tmp;
		ps->capacity = newcapacity;
	}
}

void SqListPushBack(SL* ps, SLDataType x)
{
	//如果没有空间,或者空间不足,那么就扩容
	SqListCheckCapacity(ps);

	ps->data[ps->size] = x;
	ps->size++;
}

void SqListPopBack(SL* ps)
{
	//温柔方式
	if (ps->size > 0)
	{
		ps->size--;
	}
	else
	{
		printf("SqList has already been null. Fail to destroy!\n");
	}
	
	或者采用以下方式
	//assert(ps->size > 0); //断言,括号内条件为假时,直接终止程序运行并报错。
	//ps->size--;
}

void SqListPushFront(SL* ps, SLDataType x)
{
	SqListCheckCapacity(ps);

	// 挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->data[end + 1] = ps->data[end];
		end--;
	}
	ps->data[0] = x;
	ps->size++;
}

void SqListPopFront(SL* ps)
{
	assert(ps->size > 0); // 有数据才删
	
	int begin = 1;
	while (begin < ps->size )
	{
		ps->data[begin-1] = ps->data[begin];
		begin++;
	}
	ps->size--;
}

int SqListFind(SL* ps, SLDataType x)
{
	int index = -1;
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->data[i] == x)
		{
			index = i;
			break;
		}
	}
	return index;
}

void SqListInsert(SL* ps, int pos, SLDataType x)
{
	//不允许在已用数据区外插入数据
	assert(pos <= ps->size && pos >= 0);

	SqListCheckCapacity(ps);
	
	int end = ps->size;
	while (end > pos)
	{
		ps->data[end] = ps->data[end - 1];
		end--;
	}
	ps->data[pos] = x;
	ps->size++;
}

void SqListErase(SL* ps, int pos)
{
	//只允许在有效数据区内操作
	assert(pos >= 0 && pos < ps->size);
	
	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->data[begin - 1] = ps->data[begin];
		begin++;
	}
	ps->size--;
}

Test.c 测试用例

#pragma once
#include "SqList.h"
#include<stdio.h>
#include<stdlib.h>

void TestSqList1() 
{
	SL sl;
	SqListInit(&sl);
	SqListPushBack(&sl, 1);
	SqListPushBack(&sl, 2);
	SqListPushBack(&sl, 3);
	SqListPushBack(&sl, 4);
	SqListPushBack(&sl, 5);
	
	SqListPrint(&sl);

	SqListPopBack(&sl);
	SqListPopBack(&sl);
	SqListPopBack(&sl);
	SqListPopBack(&sl);
	SqListPopBack(&sl);
	SqListPopBack(&sl);
	SqListPopBack(&sl);
	SqListPopBack(&sl);


	SqListPrint(&sl);

	SqListPushBack(&sl, 1);
	SqListPrint(&sl);

	SqListDestroy(&sl);
}

void TestSqList2()
{
	SL sl;
	SqListInit(&sl);
	SqListPushBack(&sl, 1);
	SqListPushBack(&sl, 2);
	SqListPushBack(&sl, 3);
	SqListPushBack(&sl, 4);
	SqListPushBack(&sl, 5);
	SqListPrint(&sl);

	SqListPushFront(&sl, 10);
	SqListPushFront(&sl, 20);
	SqListPushFront(&sl, 30);
	SqListPushFront(&sl, 40);
	SqListPushFront(&sl, 50);
	SqListPrint(&sl);

	SqListPopFront(&sl);
	SqListPopFront(&sl);
	SqListPrint(&sl);

	SqListDestroy(&sl);
}

void TestSqList3()
{
	SL sl;
	SqListInit(&sl);
	SqListPushBack(&sl, 1);
	SqListPushBack(&sl, 2);
	SqListPushBack(&sl, 3);
	SqListPushBack(&sl, 4);
	SqListPushBack(&sl, 5);
	SqListPrint(&sl);

	printf("%d\n", SqListFind(&sl, 5));
	printf("%d\n", SqListFind(&sl, 10));
	SqListPrint(&sl);

	SqListDestroy(&sl);
}

void TestSqList4()
{
	SL sl;
	SqListInit(&sl);
	SqListPushBack(&sl, 1);
	SqListPushBack(&sl, 2);
	SqListPushBack(&sl, 3);
	SqListPushBack(&sl, 4);
	SqListPrint(&sl);

	SqListInsert(&sl, 1, 10);
	SqListInsert(&sl, 5, 10);
	SqListPrint(&sl);
	
	SqListErase(&sl, 0);
	SqListPrint(&sl);
	SqListErase(&sl, 4);
	SqListPrint(&sl);
	SqListErase(&sl, 2);
	SqListPrint(&sl);

	SqListDestroy(&sl);
}

int main() {
	
	//TestSqList1();

	//TestSqList2();

	//TestSqList3();

	TestSqList4();

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值