动态顺序表的增删查改

目的:实现顺序表的增删查改

头插

头删

尾插

尾删

中间插

中间删

删除顺序表


什么是顺序表?

其实就是一个结构体里面存个数组

1.那就先创建一个结构体:a是数组,size是数组当前元素个数,capacity是数组元素个数最大容量

typedef struct SeqList
{
	SLDateType* a;// 指向动态开辟的数组
	int size;// 有效数据个数
	int capacity;// 容量空间的大小
}SeqList;

这里用的整形数组所以:

typedef int SLDateType;

2.1 初始化结构体;

void SeqListInit(SeqList* ps);

 开辟一个动态内存空间

其中先定义最大元素个数:INIT_CAPACITY

#define INIT_CAPACITY 4

void SeqListInit(SeqList* ps)//初始化顺序表(结构体)
{
	ps->a = (SLDateType*)malloc(sizeof(SLDateType) * INIT_CAPACOTY);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->size = 0;
	ps->capacity = INIT_CAPACITY;
}

2.2 先搞简单的:尾插

void SeqListPushBack(SeqList* ps, SLDateType x);

x是尾插的元素

注意:如果size=capacity,表示已经装满了需要扩容。不扩容尾插就越界了

void SeqListPushBack(SeqList* ps, SLDateType x)//尾插
{
	if (ps->size == ps->capacity)//判断是否需要扩容
	{
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->capacity *= 2;
		ps->a = tmp;
	}
	ps->a[ps->size] = x;
	ps->size++;
}

上图:


还有个打印顺序表:

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

void SeqListPrint(SeqList* ps)//打印顺序表
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

2.3 尾删:

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

尾删包括接下来的头删都需要判断数组是否为空 

void SeqListPopBack(SeqList* ps)//尾删
{
	if (ps->size == 0)
		return;
    ps->a[ps->size-1] = '\0';
	ps->size--;
}

上图:

2.4 头插:

void SeqListPushFront(SeqList* ps, SLDateType x);//头查

头插是从头开始插入,如果输入1 2 3  4,输出4 3 2 1.

逻辑:数组内的元素依次往后挪一个位置,就是覆盖,然后插入数据

void SeqListPushFront(SeqList* ps, SLDateType x)//头插
{
	if (ps->size == ps->capacity)//判断是否需要扩容
	{
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->capacity *= 2;
	}
	for (int i = ps->size - 1; i >= 0; i--)
	{
		ps->a[i+1] = ps->a[i];
	}
	ps->a[0] = x;
	ps->size++;
}

上图:

 

2.5 头删 

逻辑:把第一个元素覆盖了,然后size--

void SeqListPopFront(SeqList* ps)

注意:这里i<=size,如果只是小于size会越界,下面有i+1 

void SeqListPopFront(SeqList* ps)//头删
{
	if (ps->size == 0)
		return;
	int i = 0;
	for (i = 0; i <= ps->size; i++)
	{
		ps->a[i] = ps->a[i+1];
	}
    ps->a[ps->size-1] = '\0';
	ps->size--;
}

上图:

2.6 中间插

这里原理以我的理解是头插和尾插结合,比如要在第五个元素插入数据,那就把第5个包括以后往后挪一个位置,再在尾插到第4个后面

void SeqListInsert(SeqList* ps, int pos, SLDateType x)

 这里就要判断是否为空,或者是否满了,两个都要判断

void SeqListInsert(SeqList* ps, int pos, SLDateType x)// 顺序表在pos位置插入x
{
	if (ps->size == 0)
		return;
	if (ps->size == ps->capacity)//判断是否需要扩容
	{
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->capacity *= 2;
	}
	for (int i = ps->size - 1; i >= pos-1; i--)//找到pos的位置往后移
	{
		ps->a[i + 1] = ps->a[i];
	}
	ps->size++;
	ps->a[pos-1] = x;//再给pos的位置赋值
}

上图:

这里在第5个位置插入了10 

2.7 中间删

void SeqListErase(SeqList* ps, int pos)

原理:比如是第pos个,从pos往后给它覆盖了 

void SeqListErase(SeqList* ps, int pos)
{
	if (ps->size == 0)
		return;
	int i = 0;
	for (i = pos - 1; i < ps->size; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
    ps->a[ps->size-1] = '\0';
	ps->size--;
}

上图:

3. 破环顺序表 

void SeqListDestroy(SeqList* ps)

把申请的动态空间还给操作系统,让size和capacity归0

void SeqListDestroy(SeqList* ps)//破坏顺序表
{
	free(ps->a);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

还差个查找忘记写了,其实就按照size的下标找到打印就好了

里面的申请动态空间函数可以单独写出了再调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值