顺序表的动态存储

顺序表是一种线性结构,通常用数组实现。数组可分为静态和动态两种,静态顺序表使用固定大小的数组,而动态顺序表则利用动态开辟的数组存储数据。本文将重点探讨动态顺序表的操作,包括其在C语言中的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

  1. 静态顺序表:使用定长数组存储。

  2. 动态顺序表:使用动态开辟的数组存储。
    // 顺序表的静态存储

    #define N 100
             typedef int SLDataType;
             typedef struct SeqList
             {
             SLDataType array[N]; // 定长数组
             比特科技
             size_t size; // 有效数据的个数
             }SeqList;
    

// 顺序表的动态存储

typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;

这里来看一下动态存储
Seq.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define SLDataType int

typedef struct SeqList
{
	SLDataType *arry;   //动态数组
	size_t _size;       //数组里当前存储的数量
	size_t _capicity;   //数组的容量
}SeqList; 

void SeqListInit(SeqList *psl, size_t capicity);//初始化顺序表

void SeqListDestory(SeqList *psl);//清空顺序表

void CheckCapicity(SeqList *psl);//检查顺序表

void SeqListPushbBack(SeqList *psl, SLDataType x);//尾插

void SeqListPopBack(SeqList *psl);//尾删

void SeqListPushFront(SeqList *psl, SLDataType x);//头插

void SeqListPopFront(SeqList *psl);//头删

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

int SeqListFind(SeqList *psl,SLDataType x);//查找顺序表中元素

void SeqListInsert(SeqList *psl, SLDataType x, size_t pos);//任意位置插入元素

void SeqListErase(SeqList *psl, size_t pos);//删除一个位置的元素

void SeqListRemove(SeqList *psl, SLDataType x);//删除所有x元素

void SeqListModify(SeqList *psl, size_t pos, SLDataType x);//修改某个位置的元素

Seq.c

#include"Seq.h"

void SeqListInit(SeqList *psl, size_t capicity)
{
	assert(psl);
	psl->_size = 0;
	psl->_capicity = capicity;
	psl->arry =(SeqList*)malloc((psl->_capicity)*sizeof(SLDataType));//动态开辟元素个数为capicity的数组
}

void SeqListDestory(SeqList *psl)
{
	assert(psl);
	psl->_size = 0;
	psl->_capicity = 0;//该函数也可以用malloc将数组重新分配为0
}

void CheckCapicity(SeqList *psl)
{
	assert(psl);
	if (psl->_size == psl->_capicity && psl->_capicity > 0)//如果存满了
	{
		psl->_capicity *= 2;
		psl->arry = (SeqList*)realloc(psl->arry,sizeof(SLDataType)*(psl->_capicity));//2倍扩展
	}
	if (psl->_capicity == 0)//如果容量为0
	{
		psl->_capicity = 5;
		psl->arry = (SeqList*)malloc(sizeof(SLDataType)*5);
	}
}

void SeqListPushbBack(SeqList *psl, SLDataType x)
{
	assert(psl);
	CheckCapicity(psl);//插入时注意要检查容量是否满了
	psl->arry[psl->_size] = x;
	psl->_size++;
}

void SeqListPopBack(SeqList *psl)
{
	assert(psl);
	CheckCapicity(psl);//删除时要注意是否容量为0
	psl->_size--;
}

void SeqListPushFront(SeqList *psl,SLDataType x)
{
	assert(psl);
	CheckCapicity(psl);
	size_t flag = psl->_size;//设置一个从后面开始的标记
	while (flag > 0)//先把所有元素从后面开始往后挪动一位
	{
		psl->arry[flag] = psl->arry[flag - 1];
		flag--;
	}
	psl->arry[0] = x;//挪动完把插入的元素放在首位,即插入成功
	psl->_size++;
}

void SeqListPopFront(SeqList *psl)
{
	assert(psl);
	CheckCapicity(psl);
	size_t start = 0;//头删只需要把第一个后面的所有元素一个个往前面挪动即可
	while (start < psl->_size-1)
	{
		psl->arry[start] = psl->arry[start + 1];
		start++;
	}
	psl->_size--;
}

void SeqListPrint(SeqList *psl)
{
	assert(psl);
	int i = 0;
	for (i = 0; i < psl->_size; i++)//注意打印的是实际存储的元素,不是capicity
	{
		printf("%d,", psl->arry[i]);
	}
}

int SeqListFind(SeqList *psl, SLDataType x)
{
	assert(psl);
	int i = 0;
	for (; i < psl->_size; i++)
	{
		if (psl->arry[i] == x)
		{
			return i;//只是查找了第一个是x的元素的下标
		}
	}
	return -1;
}

void SeqListInsert(SeqList *psl, SLDataType x, size_t pos)
{
	assert(psl);
	CheckCapicity(psl);//检查是否满了
	size_t start = psl->_size;
	while (start > pos-1) //将pos和pos后面的元素,从最后面开始向后挪动
	{
		psl->arry[start] = psl->arry[start - 1];
		start--;
	}
	psl->arry[pos - 1] = x;
	psl->_size++;
}

void SeqListErase(SeqList *psl, size_t pos)
{
	assert(psl);
	CheckCapicity(psl);
	size_t start = pos;
	while (start < psl->_size)//将pos之后的元素从pos开始不断的向前挪动
	{
		psl->arry[start-1] = psl->arry[start];
		start++;
	}
	psl->_size--;
}

void SeqListRemove(SeqList *psl, SLDataType x)
{                      //把所有是x的元素删除
	assert(psl);
	CheckCapicity(psl);
	size_t left = 0;
	size_t right = 0;
	while (right<psl->_size)//类似双指针,right向后走,把不等于x的给left,最后结果就是没有x的结果
	{
		if (x != psl->arry[right])
		{
			psl->arry[left] = psl->arry[right];
			left++;
		}
		right++;
	}
	psl->_size = left;
}

void SeqListModify(SeqList *psl, size_t pos, SLDataType x)
{
	assert(psl);
	if (pos >= psl->_size)//如果输入的位置超出的实际存储的数量,则不操作
	{
		return;
	}
	psl->arry[pos - 1] = x;
}

test.c

#include"Seq.h"

int main()
{
	SeqList psl;
	SeqListInit(&psl,5);
	SeqListPushFront(&psl, 1);
	SeqListPushFront(&psl, 1);
	SeqListPushFront(&psl, 2);
	SeqListPushFront(&psl, 1);
	SeqListPushFront(&psl, 3);
	SeqListPushFront(&psl, 5);
	SeqListPushFront(&psl, 1);
	SeqListPushFront(&psl, 1);

	SeqListPrint(&psl);
	printf("\n");
	SeqListRemove(&psl, 1);
	SeqListPrint(&psl);
	printf("\n");
	SeqListModify(&psl, 4, 4);
	SeqListPrint(&psl);
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值