数据结构——动态顺序表

数据结构的动态顺序表有以下几个操作:创建,销毁,初始化,增删查改和打印以及内存空间不够时的扩容

本文的宏定义:

#define SeqTypeData int

1.动态顺序表的创建

typedef struct SeqListInit{
	//动态顺序表的创建
	SeqTypeData* a;
	int size;//实际有效空间
	int capacity;//申请空间大小
}SL;

2.动态顺序表的销毁

void SeqListDestroy(SL* ps) {//顺序表销毁
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
};

值得注意的是,ps->a要赋值NULL,避免野指针的出现。

3.动态顺序表的初始化

void SeqListInit(SL* ps){//顺序表初始化
	ps->a = NULL;
	ps->capacity = ps->size = 0;
};

4.动态顺序表的增加

插入时都要判断空间是否足够,是否需要扩容,以及ps->size要加一。

(1)头插

void SeqListPushFront(SL* ps, SeqTypeData x) {//顺序表头插
	SeqListCheckCapacity(ps);//判断是否需要扩容
	//挪动数据
	ps->size++;
	for (int i = 0; i < ps->size; i++) {
		ps->a[ps->size - i] = ps->a[ps->size - i - 1];
	}
	ps->a[0] = x;
}

头插也就是把数据都向后挪一位,再给第一位赋值。

(2)尾插

void SeqListPushBack(SL* ps, SeqTypeData x) {//顺序表尾插
	SeqListCheckCapacity(ps);//判断是否需要扩容
	ps->a[ps->size++] = x;
}

(3)任意位置插入

void SeqListInsert(SL* ps, int adr, SeqTypeData x)//adr为逻辑地址,等于数组下标加一
{
	if (adr > (ps->size + 1) || adr < 1)
	{
		printf("adr invalid\n");
		return;
	}
	SeqListCheckCapacity(ps);//判断是否需要扩容
	int end = ps->size ;
	while (end >= adr-1)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[adr-1] = x;
	ps->size++;
}

任意位置插入要记得判断插入位置的合法性,再将插入位置的数据向后移一位,再在插入位置赋值即可。

5.动态顺序表的删除

进行删除操作时,要判断表是否已经是空表,此时不可再删。删除成功时,ps->size减一。

(1)头删

void SeqListPopFront(SL* ps) {//顺序表头删
	if (ps->size == 0)
	{
		printf("顺序表为空,不可再删\n");
	}
	else
	{
		for (int i = 0; i < ps->size; i++) {
			ps->a[i] = ps->a[i+1];
		}
		ps->size--;
	}
}

(2)尾删


void SeqListPopBack(SL* ps) {//顺序表尾删
	if (ps->size--);
	else
	{
		printf("顺序表为空,不可再删\n");
	}
}

(3)任意位置删除

void SeqListErase(SL* ps, int adr) {
	if (ps->size == 0)
	{
		printf("顺序表为空,不可再删\n");
	}
	if (adr > (ps->size + 1))
	{
		printf("删除位置错误\n");
	}
	for (int i = adr; i < ps->size; i++) {
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}

任意位置的删除也要检验删除位置的合法性。

6.动态顺序表的任意位置的修改

void SeqListCheck(SL* ps, int adr, SeqTypeData x) {//adr为逻辑地址,等于数组下标加一
	if(adr>(ps->size+1))
		printf("修改位置错误\n");
	else
	ps->a[adr - 1] = x;
}

任意位置的修改也要检验删除位置的合法性。

7.顺序表的打印

void SeqListPrint(SL ps) {//顺序表打印
	for (int i = 0; i < ps.size; i++)
	{
		printf("%d ", ps.a[i]);
	}
}

8.动态顺序表的扩容

void SeqListCheckCapacity(SL* ps) {//顺序表检查是否需要扩容
	if (ps->size == ps->capacity) {
		SeqTypeData newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SeqTypeData* tem = (SeqTypeData*)realloc(ps->a, newcapacity * sizeof(SeqTypeData));
		if (tem == NULL) {
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tem;
		ps->capacity = newcapacity;
	}
}

9.全部代码

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"


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


void SeqListInit(SL* ps){//顺序表初始化
	ps->a = NULL;
	ps->capacity = ps->size = 0;
};

void SeqListDestroy(SL* ps) {//顺序表销毁
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
};

void SeqListPrint(SL ps) {//顺序表打印
	for (int i = 0; i < ps.size; i++)
	{
		printf("%d ", ps.a[i]);
	}
	if (ps.size == 0)
		printf("顺序表为空");
	printf("\n");
}

//int SeqListCapacity(SL* ps) {//
//	return ps->capacity;
//}

void SeqListPushBack(SL* ps, SeqTypeData x) {//顺序表尾插
	SeqListCheckCapacity(ps);
	ps->a[ps->size++] = x;
}

void SeqListPushFront(SL* ps, SeqTypeData x) {//顺序表头插
	SeqListCheckCapacity(ps);
	//挪动数据
	ps->size++;
	for (int i = 0; i < ps->size; i++) {
		ps->a[ps->size - i] = ps->a[ps->size - i - 1];
	}
	ps->a[0] = x;
}

void SeqListCheckCapacity(SL* ps) {//顺序表检查是否需要扩容
	if (ps->size == ps->capacity) {
		SeqTypeData newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SeqTypeData* tem = (SeqTypeData*)realloc(ps->a, newcapacity * sizeof(SeqTypeData));
		if (tem == NULL) {
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tem;
		ps->capacity = newcapacity;
	}
}

void SeqListPopBack(SL* ps) {//顺序表尾删

	if (ps->size--);
	else
	{
		printf("顺序表为空,不可再删\n");
	}
}

void SeqListPopFront(SL* ps) {//顺序表头删
	if (ps->size == 0)
	{
		printf("顺序表为空,不可再删\n");
	}
	else
	{
		for (int i = 0; i < ps->size; i++) {
			ps->a[i] = ps->a[i+1];
		}
		ps->size--;
	}
}

void SeqListFind(SL ps, SeqTypeData x) {//顺序表查找
	/*int cnt;*/
	for (int i = 0; i < ps.size; i++) {
		if (ps.a[i] == x) {
			printf("%d", i + 1);//返回逻辑下标
			/*cnt++;*/
		}
	}
	/*if (cnt == 0)
		printf("没有这个数字");*/
}

void SeqListInsert(SL* ps, int adr, SeqTypeData x)//adr为逻辑地址,等于数组下标加一
{
	if (adr > (ps->size + 1) || adr < 1)
	{
		printf("adr invalid\n");
		return;
	}
	SeqListCheckCapacity(ps);
	int end = ps->size ;
	while (end >= adr-1)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[adr-1] = x;
	ps->size++;
}

void SeqListErase(SL* ps, int adr) {//adr为逻辑地址,等于数组下标加一
	if (ps->size == 0)
	{
		printf("顺序表为空,不可再删\n");
	}
	if (adr > (ps->size + 1))
	{
		printf("删除位置错误\n");
	}
	for (int i = adr; i < ps->size; i++) {
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}

void SeqListCheck(SL* ps, int adr, SeqTypeData x) {
	if(adr>(ps->size+1))
		printf("修改位置错误\n");
	else
	ps->a[adr - 1] = x;
}

void menu()
{
	printf("请选择\n");
	printf("********1.头插  2.尾插********\n");
	printf("********3.头删  4.尾删********\n");
	printf("********5.随插  6.随删********\n");
	printf("********7.查找  8.打印********\n");
	printf("********9.修改  0.退出********\n");
	printf("请选择\n");
}


int main()
{
	int input;
	SL ps;
	SeqTypeData x;
	int adr;
	SeqListInit(&ps);
	do {
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入头插数字\n");
			scanf("%d", &x);
			SeqListPushFront(&ps, x);
			break;
		case 2:
			printf("请输入尾插数字\n");
			scanf("%d", &x);
			SeqListPushBack(&ps, x);
			break;
		case 3:
			SeqListPopFront(&ps);
			break;
		case 4:
			SeqListPopBack(&ps);
			break;
		case 5:
			printf("请输入插入位置和数字\n");
			scanf("%d%d", &adr, &x);
			SeqListInsert(&ps, adr, x);
			break;
		case 6:
			printf("请输入删除位置\n");
			scanf("%d", &adr);
			SeqListErase(&ps, adr);
			break;
		case 7:
			printf("请输入查找数字\n");
			scanf("%d", &x);
			SeqListFind(ps, x);
			break;
		case 8:
			SeqListPrint(ps);
			break;
		case 9:
			printf("请输入修改位置和数字\n");
			scanf("%d%d", &adr, &x);
			SeqListCheck(&ps, adr, x);
			break;
		case 0:
			printf("正在退出中");
			break;
		}
	} while (input);
	return 0;
}

10.效果展示

由于图片大小问题,只展示了部分功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/461160.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自学rabbitmq入门到精通

交换机的fault &#xff08;发布与订阅模式&#xff09; 因为消息是由生产者发送给excahnge&#xff0c;exchange发送给队列&#xff0c; 然后由队列发送给消费者的。 展示使用图形化界面使用fanout模式。 创建交换机 然后创建三个队列&#xff0c;绑定对应的交换机&#xff…

docker的常用指令

docker的常用指令 从docker镜像仓库&#xff0c;搜索所有和mysql有关的镜像 docker search mysql 从docker仓库拉取mysql docker pull mysql这里的mysql是指使用search搜索出来的所有容器的NAME 如果和我一样遇到以下问题&#xff1a; 我可以登录阿里云的官网&#xff0c;找…

[mysql面试必备技能]-一条SQL的执行过程

天天和数据库打交道&#xff0c;一天能写上几十条 SQL 语句&#xff0c;但你知道我们的系统是如何和数据库交互的吗&#xff1f;MySQL 如何帮我们存储数据、又是如何帮我们管理事务&#xff1f;....是不是感觉真的除了写几个 「select * from dual」外基本脑子一片空白&#xf…

使用Python打造一款摸鱼倒计时界面

目录 一、引言 二、需求分析 三、技术选型 四、代码实现 导入必要的库和模块 创建主窗口 添加倒计时设置和显示组件 实现倒计时逻辑 运行主循环 五、案例测试与优化 六、总结 一、引言 在日常的工作和生活中&#xff0c;我们经常会遇到需要暂时离开工作岗位的情况&…

Docker容器化技术(使用Dockerfile制作镜像)

Docker中的镜像分层 Docker 支持通过扩展现有镜像&#xff0c;创建新的镜像。实际上&#xff0c;Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。 1、Docker 镜像为什么分层 镜像分层最大的一个好处就是共享资源。 比如说有多个镜像都从相…

springboot“力炫”健身馆网站

摘要 随着网络科技的不断发展以及人们经济水平的逐步提高&#xff0c;网络技术如今已成为人们生活中不可缺少的一部分&#xff0c;而信息管理系统是通过计算机技术&#xff0c;针对用户需求开发与设计&#xff0c;该技术尤其在各行业领域发挥了巨大的作用&#xff0c;有效地促…

当前组件端口莫名增加127.0.0.1:3658和8563

当部署组件到服务器中&#xff0c;可以通过下方的命令查询服务pid占用的端口&#xff0c; netstat -nap |grep PID | grep LISTEN查询之后发现除了自己组件的端口还增加 百思不得其解后&#xff0c;知道了3658 8563端口是近期使用的arthas组件的端口&#xff0c; 启动arthas组…

ROS——集成开发环境搭建

1.4 ROS集成开发环境搭建 和大多数开发环境一样&#xff0c;理论上&#xff0c;在 ROS 中&#xff0c;只需要记事本就可以编写基本的 ROS 程序&#xff0c;但是工欲善其事必先利其器&#xff0c;为了提高开发效率&#xff0c;可以先安装集成开发工具和使用方便的工具:终端、ID…

基于GT911触控IC的电容屏在MSP430上的驱动

背景 最近参加公司一个电池测试仪的项目&#xff0c;负责电容屏驱动开发&#xff0c;电容屏的触控IC是汇顶科技的GT911&#xff0c;电容屏的总线接口是I2C。 因为项目沟通方面的失误&#xff0c;本应接到主控芯片的电容屏&#xff0c;被连到了MSP430这款负责供电管理的MCU&…

NCP1380BDR2G芯片中文资料规格书PDF数据手册引脚图图片参数功能价格

产品描述&#xff1a; NCP1380 是一款高性能器件&#xff0c;旨在为准谐振转换器供电。该控制器基于专属的谷锁闭系统&#xff0c;可以在功率负载变轻时进行切换并降低开关频率。这样将产生稳定的运行&#xff0c;即使在漏极-源极谷中总是触发的开关事件下也是如此。此系统可在…

关于数据文件上传到服务器的格式及上传实现的方法

文件上传的格式&#xff1a; 第一种&#xff1a;form-data格式的&#xff1a; let fm new FormData; fm.append(file,file) fm.append(filename, ) // 在请求体中进行添加请求头的信息 axios.post(https://127.0.0.1:8888/upload_single,fm,{ headers:{ …

SPI机制详解

SPI机制详解 什么是SPI机制&#xff1f; SPI&#xff1a;Service Provider Interface&#xff0c;中文直译&#xff1a;服务提供者接口&#xff0c;它通过在ClassPath路径下的META-INF/service文件夹中查找文件&#xff0c;并自动加载文件里所定义的类 在面向对象的设计原则…

踩坑(乱改配置,电脑都打不开,无奈暴力重装)文末有惊喜喔

总结我的论文项目的傻逼开端。&#xff08;想的很好&#xff0c;思路也对&#xff0c;也做了&#xff0c;但是过程和结果好像并不是想象中那么容易&#xff09; 故事讲解&#xff1a; 本来我只有一台电脑&#xff0c;这个电脑上面东西比较杂。学习资料呀&#xff0c;笔记呀&a…

【使用postman测试python接口】

打开python服务 设置postman如下&#xff0c;并发送&#xff1a; postman新建请求设置请求方式为post设置地址、raw、json方式、内容如下 结果&#xff1a; python如下&#xff1a; from flask import Flask, request, jsonifyapp Flask(__name__) # 实例化对象app.route…

JVM理解学习

参考视频 运行时数据区 JVM架构总览图 绿色的&#xff1a;方法区&#xff0c;堆&#xff0c;是所有线程共享的 黄色的&#xff1a; 虚拟机栈&#xff0c;本地方法栈&#xff0c;程序计数器&#xff0c;是线程私有的 程序计数器 程序计数器是一块较小的内存空间&#xff0c;物…

macbook安装brew出现错误解决办法

我是使用国内的源安装brew的时候&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 我选择了 1: 就出错了&#xff0c;后来切换为2重新安装就好了 安装完成后提示获取不到系统版本&#xff1a; Failed to co…

Linux使用Docker部署Registry结合内网穿透实现公网远程拉取推送镜像

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

Linux服务器(Debian系)包含UOS安全相关巡检shell脚本

#!/bin/bash# Define output file current_date$(date "%Y%m%d") # Gets the current date in YYYYMMDD format output_file"server_security_inspection_report_${current_date}.txt"# Empty the file initially echo > $output_file# 获取巡检时间 (…

Hadoop学习1:概述、单体搭建、伪分布式搭建

文章目录 概述基础知识Hadoop组件构成Hadoop配置文件 环境准备配置Hadoop配置下载配置环境变量 Hadoop运行模式Standalone Operation&#xff08;本地&#xff09;官方DemoWordCount单词统计Demo Pseudo-Distributed Operation&#xff08;伪分布式模式&#xff09;配置修改启动…

NCV4275CDT50RKG稳压器芯片中文资料规格书PDF数据手册引脚图图片价格功能

产品概述&#xff1a; NCV4275C 是一款低漏稳压器&#xff0c;可用于严酷汽车环境。它包括了较宽的运行温度范围和输出电压范围。输出调节为 5.0 V 或 3.3 V&#xff0c;额定输出电流为 450 mA。它还提供过电流保护、超温保护和可编程微处理器重置等多种功能。NCV4275C 采用 D…