顺序表各项功能的实现

目录

1>>闲话

2>>顺序表尾删

3>>顺序表的头插和头删

3.1>>头插

3.2>>头删

4>>指定位置插入和删除

4.1>>指定位置插入

4.2>>指定位置删除

5>>查找

6>>查找替换修改

7>>销毁

8>>三个文件代码

test.c

seqlist.h

seqlist.c

9>>结语


1>>闲话

        大家国庆玩的开心不?小编是在国庆恶补了c的知识,然后玩了两天,给大家一个方法:节假日先学习,学习的天数一定要大于玩的天数,不然会一直想玩,假设你先玩两天,再想学习,你会发现很难学进去,因为你的心思早已不在,所以,先学习巩固完知识在玩是比较好的,小编就学了四天,玩了两天半。好了废话不多说,接着上一篇顺序表的博客,完善一下顺序表剩下的内容。

2>>顺序表尾删

        删除尾部的数据较为容易,只需要传结构体变量指针就好

因此它的声明比较简单如上图。

它功能的实现,不用想的那么复杂,例如:该怎么把尾部数据置为0或者空呢?等等,其实只需要将有效数据也就是size减减就好,因为后续增加数据把原来删除的给覆盖了。

这里怕有同学忘记了上篇博客,附上顺序表的三个元素;

3>>顺序表的头插和头删

3.1>>头插

        头插和头删跟尾部差不多,先看代码,然后我一一解释:

声明如上,x表示要插入的数。

首先要想实现头插,就要先判断传进来的地址是不是空地址,用assert断言判断,后面的功能实现也包括assert,后面就不在解释,接着,需要判断还有没有剩余空间可以插入,就要进入函数nospace中:

当ps指向的size和capacity相同时,说明空间不够了,拿一个新的变量newcapacity来存储,防止错误数据覆盖,三目操作符如果是0,也就是刚刚初始化,那么就置为4,如果不是0,那么就将原来的大小乘2;再接着,给一个新的指针tmp类型是datetype*,使用realloc进行扩容,扩容的大小还需要乘上一个sizeof(datetype)因为如果整形的话那么就要增大4倍;再者,判断tmp是否为空指针,如果不是则执行,是则打印错误信息。最后将新的指针赋给arr,然后新的空间大小给capacity

接着返回来,实现头插部分:

头插也就是在下标0处插入,那么整体数据就要向后移动,如下图

因此循环从size开始然后--并且大于0,当循环结束对0下标进行赋值插入即可,然后size(有效数据个数)别忘记加加!

3.2>>头删

这里就是把头部也就是0下标之后的数据都往前移动一位,然后将size--就好,代码思路和前面都差不多,这里就不赘述啦,有问题欢迎评论区点出来~

4>>指定位置插入和删除

        若是上面都搞懂了,接下来就比较容易理解啦:

4.1>>指定位置插入

        

声明中,pos表示在哪个下标插入,x表示插入的数据

这里的assert还要加一行pos在有效范围内噢别忘记了

当pos等于0是就表示头插,当pos等于size时就表示尾插

插入还是和之前一样,需要用nospace函数判断空间够不够,然后将pos以及pos后的整体数据往后移动,插入的数据赋值给pos位置的数据,size加加就结束啦!

4.2>>指定位置删除

这个也比较简单,不过注意size的有效范围和插入不一样哟!

然后将pos后的整体数据往前移动即可。

5>>查找

这里代码也和前面的大抵相同,就是注意返回类型从void变为了int,因为返回的是下标,这里都不过多赘述啦,大家看看代码。

6>>查找替换修改

这个其实是修改和查找的组合

解读:查找99,返回下标,将此下标对应的数也就是99,替换为88.

7>>销毁

在我们不断的进行增删查改后,那么就要对它进行销毁并重置,这里首先判断arr是不是一个有效的指针,是的话那么就释放,然后置为空指针,size和capacity置为0;

最后让我们来测试一下吧:

8>>三个文件代码

test.c

#include"seqlist.h"

void SLtest() 
{
	SL sl;
	SLset(&sl);//初始化
	SLpushback(&sl, 1);	//尾插
	SLprint(&sl);
	SLpushback(&sl, 2);	//尾插
	SLprint(&sl);	SLpushback(&sl, 3);	//尾插
	SLprint(&sl);	SLpushback(&sl, 4);	//尾插
	SLprint(&sl);	SLpushback(&sl, 5);	//尾插
	SLprint(&sl);	SLpushback(&sl, 6);	//尾插
	SLprint(&sl);
	SLpushstart(&sl, 2);//头插
	SLprint(&sl);	SLpushstart(&sl, 3);//头插
	SLprint(&sl);	SLpushstart(&sl, 4);//头插
	SLprint(&sl);
	SLfind(&sl, 4, 99);
	SLprint(&sl);
	SLdfind(&sl, 2);
	SLprint(&sl);
	SLdback(&sl);
	SLprint(&sl);
	SLseedg(&sl, SLseed(&sl, 99) , 88);
	SLprint(&sl);
	SLruin(&sl);
	SLprint(&sl);
	system("pause");
}
int main() 
{

	SLtest();
	return 0;
}

seqlist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<Windows.h>
typedef int datetype;//不知道具体类型,可以一下子改

typedef struct seqlist {
	datetype* arr;//(顺序表数组实现增、删、改、查)动态顺序表
	int size;//有效数据
	int capacity;//容量(包含有效和浪费的数据)
}SL;//将struct seqlist 重命名为typedef

void SLset(SL* ps);//初始化声明

void SLpushback(SL* ps, datetype x);//尾插

void SLdback(SL* ps);//尾删

void SLpushstart(SL* ps, datetype x);//头插

void SLdstart(SL* ps);//头删除

void SLprint(SL* ps);//打印

void SLfind(SL* ps, int pos, datetype x);//指定位置插入

void SLdfind(SL* ps, int pos);//指定位置删除

int SLseed(SL* ps, datetype x);//查找

void SLseedg(SL* ps, int pos,datetype x); //查找替换修改

void SLruin(SL* ps);//销毁

seqlist.c


#include"seqlist.h"

void SLset(SL* ps) {
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
void nospace(SL* ps) {
	
	if (ps->size == ps->capacity) {
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		datetype* tmp = (datetype*)realloc(ps->arr, newcapacity * sizeof(datetype));
		if (tmp == NULL) {
			perror("realloc");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
	
}
void SLpushback(SL* ps, datetype x) {//x是插入数据
	//情况2:空间不够进行扩容
	nospace(ps);
	ps->arr[ps->size++] = x;//情况1:空间够直接加
}
void SLpushstart(SL* ps, datetype x) {//头插
	assert(ps);
	nospace(ps);
	for (int i = ps->size; i >0 ; i--) {
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}
void SLprint(SL* ps) {
	for (int i = 0; i < ps->size ; i++) {
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}
void SLdstart(SL* ps) {
	assert(ps && ps->size);
	for (int i = 0; i < ps->size-1; i++) {
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}
void SLdback(SL* ps) {
	assert(ps && ps->size);
	ps->size--;
}

void SLfind(SL* ps, int pos, datetype x) {
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	nospace(ps);
	for (int i = ps->size; i > pos; i--) {
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}


void SLdfind(SL* ps, int pos) {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size - 1; i++) {
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

int SLseed(SL* ps, datetype x) {
	assert(ps);
	for (int i = 0; i < ps->size; i++) {
		if (ps->arr[i] == x) {
			printf("找到了,下标是%d\n",i);
			return i;
		}
	}
	printf("没找到\n");
	return 0;
}

void SLseedg(SL* ps, int pos, datetype x) {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	ps->arr[pos] = x;
}

void SLruin(SL* ps) {
	if (ps->arr )
		free(ps->arr);
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

大家可以自己测试然后试着写写。

9>>结语

        顺序表的内容就结束啦,怎么样?大家是否感觉还可以,数据结构也没那么那么难对吧,其实任何学科都一样,肯用心学,肯花心思,相信都能攻破,希望大家和我一起保持这份干劲,一直终身学下去!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

枫の大一

谢谢大佬,我会三连你的文章

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

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

打赏作者

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

抵扣说明:

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

余额充值