数据结构与算法系列之顺序表的实现

news2024/10/1 5:30:10

在这里插入图片描述

这里写目录标题

  • 顺序表的优缺点:
  • 注意事项
  • test.c(动态顺序表)
  • SeqList.h
  • SeqList.c
  • 各接口函数功能详解
    • void SLInit(SL* ps);//定义
    • void SLDestory(SL* ps);
    • void SLPrint(SL* ps);
    • void SLPushBack(SL* ps ,SLDataType * x );
    • void SLPopBack(SL* ps);
    • void SLPushFront(SL* ps,SLDataType * x );
    • void SLPopFront(SL* ps);
    • void SLCheckCapacity(SL* ps);
    • void SLInsert(SL* ps, int pos, SLDataType x);//pos位置插入
    • void SLErase(SL* ps, int pos);//pos位置删除
    • int SLFind(SL* ps, SLDataType x);

顺序表的优缺点:

优点:存储密度高,可以随机存取结点。
缺点:1.长度为定值,中途无法扩充
2.插入删除需要移动结点,效率低

注意事项

1.N个数头删和尾删的时间复杂度是O(N)
N个数头插和尾插的时间复杂度是O(N^2)
//当数组只有一个元素时,移动1次,有两个元素时,移动两次,有三个元素时移动三次… 所以成等差数列经大O表达式为(N^2)

2.柔性数组与顺序表的关系
柔性数组是与结构体变量占一个空间
而顺序表是结构体额外开辟的空间

3.不能用realloc进行缩容
//缩容之后,可能缩容的部分会被使用,在进行扩容的话,不能回到原样

4.free()
//不能在动态数组中间进行释放,必须开辟多大空间,就一次释放完

顺序表
在这里插入图片描述
柔性数组
在这里插入图片描述

test.c(动态顺序表)

int main()
{
	SL s;
	SLInit(&s);
	int option = 0;
	while (option != -1)
	{
		menu();
		scanf("%d", &option);
		if (option == 1)
		{
			printf("请依次输入要尾插的数据");
			int x = 0;
			while (x != -1)
			{
				scanf("%d", &x);
				SLPushBack(&s, x);
			}
		}
		else if (option == 7)
		{
			SLPrint(&s);
		}
	}
	return 0; 
}

SeqList.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#define INT_CAPACITY 4
typedef int  SLDataType;

typedef struct SepList
{
	SLDataType* a;
	int size;
	int capacity;
}SL;

void SLInit(SL* ps);
void SLDestory(SL* ps);
void SLPrint(SL* ps);

void SLPushBack(SL* ps ,SLDataType * x );//尾插
void SLPopBack(SL* ps);//尾删
void SLPushFront(SL* ps,SLDataType * x );//头插
void SLPopFront(SL* ps);//头删
void SLCheckCapacity(SL* ps);//扩容

void SLInsert(SL* ps, int pos, SLDataType x);//pos位置插入
void SLErase(SL* ps, int pos);//pos位置删除
int  SLFind(SL* ps, SLDataType x);
 

SeqList.c

#include "SeqList.h"
void SLCheckCapacity(SL* ps)
{

	assert(ps);
	if (ps->size == ps->capacity)
	{		//realloc 可能会原地扩容 也可能异地扩容
		SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * (ps->capacity* 2));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}

}

void SLInit(SL* ps)
{
	assert(ps);

	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*  INT_CAPACITY);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}

	ps->size = 0;
	ps->capacity = INT_CAPACITY;
}
void SLDestory(SL* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SLPushBack(SL* ps, SLDataType  x)
{
	 assert(ps);
	 SLCheckCapacity(ps);
	 //扩容
	 ps->a[ps->size++] = x;
	//SLInsert(ps,ps->size, x)尾插
}
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	/*if (ps->size == 0)
	{
		return;
	}*/
	
	ps->size--;
	//尾删SLErase(ps, ps->size-1);
}
void SLPushFront(SL* ps ,SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
	
}
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}
void SLPrint(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
}



void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);//可以等于size,相当于尾插
	SLCheckCapacity(ps);
	int end = ps->size-1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	int begin = pos + 1;

	while (begin < ps->size)
	{
		ps->a[begin-1] = ps->a[begin];
		begin++;
	}
	ps->size--; 
}


int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
			return i;
	}
	return -1;

}

各接口函数功能详解

void SLInit(SL* ps);//定义

assert(ps);//进行assert判断ps这个结构体指针是否存在

	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*  INT_CAPACITY);//使用malloc函数进行扩容,必须用free()释放 
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->size = 0;初始化
	ps->capacity = INT_CAPACITY;

void SLDestory(SL* ps);

{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

void SLPrint(SL* ps);

assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}

void SLPushBack(SL* ps ,SLDataType * x );

{
	 assert(ps);
	 SLCheckCapacity(ps);//判断是否扩容
	 //扩容
	 ps->a[ps->size++] = x;
	//SLInsert(ps,ps->size, x)尾插
}

void SLPopBack(SL* ps);

    assert(ps);
	assert(ps->size > 0);因为尾删判断数组是否有元素存在,如果没有元素则不可以尾删
	/*if (ps->size == 0)
	{
		return;
	}*/
	
	ps->size--;
	//尾删SLErase(ps, ps->size-1);

void SLPushFront(SL* ps,SLDataType * x );

{
	assert(ps);
	SLCheckCapacity(ps);//是否扩容
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
	
}

在这里插入图片描述

void SLPopFront(SL* ps);

{
	assert(ps);
	assert(ps->size > 0);
	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}

在这里插入图片描述

void SLCheckCapacity(SL* ps);

	
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{		//realloc所以扩容成功后,可能会原地扩容 也可能异地扩容,所以用ps->a = tmp来重新接收
		SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * (ps->capacity* 2));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}

}

void SLInsert(SL* ps, int pos, SLDataType x);//pos位置插入

//可用于头插和尾插

assert(ps);
	assert(pos >= 0 && pos <= ps->size);//可以等于size,相当于尾插
	SLCheckCapacity(ps);
	int end = ps->size-1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;

void SLErase(SL* ps, int pos);//pos位置删除

//可用于头删和尾删


assert(ps);
	assert(pos >= 0 && pos < ps->size);
	int begin = pos + 1;


	while (begin < ps->size)
	{
		ps->a[begin-1] = ps->a[begin];
		begin++;
	}
	ps->size--; 

int SLFind(SL* ps, SLDataType x);

assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
			return i;
	}
	return -1;

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[busybox] busybox生成一个最精简rootfs(下)

书接上回&#xff1a;[busybox] busybox生成一个最精简rootfs(上) 本篇介绍几个rootfs中用到的“不是那么重要的”几个文件。 9 /etc/shadow 和 /etc/passwd 曾经&#xff0c;/etc/passwd 文件用于存储独立 Linux 系统中的所有登录信息。 后来&#xff0c;由于以下原因&…

算法训练营 day63 单调栈 下一个更大元素II 接雨水

算法训练营 day63 单调栈 下一个更大元素II 接雨水 下一个更大元素II 503. 下一个更大元素 II - 力扣&#xff08;LeetCode&#xff09; 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的…

2023软件测试工程师涨薪攻略,3年如何达到30K

1.软件测试如何实现涨薪 首先涨薪并不是从8000涨到9000这种涨薪&#xff0c;而是从8000涨到15K加到25K的涨薪。基本上三年之内就可以实现。 如果我们只是普通的有应届毕业生或者是普通本科那我们就只能从小公司开始慢慢往上走。 有些同学想去做测试&#xff0c;是希望能够日…

Vue3 关于 provide、inject 的用法

前言&#xff1a; 在前端项目中牵扯的最多的莫过于组件之间的传值了&#xff0c;除了最最常用的 props 和 emit&#xff0c;其实在 Vue 中还额外提供了另外几种方法。今天分享一种组件之间通信的方法。 一. 场景再现 先别着急考虑标题这个 api 的含义。在这里我先动手写一个比较…

如何使用Codecepticon对C#、VBA宏和PowerShell源代码进行混淆处理

关于Codecepticon Codecepticon是一款功能强大的代码混淆处理工具&#xff0c;该工具专为红队和紫队渗透测试安全活动而开发&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以轻松对C#、VBA5/VBA6&#xff08;宏&#xff09;和PowerShell源代码进行混淆处理。Codecep…

【Datawhale图机器学习】图神经网络

图神经网络 GNN是一种连接模型&#xff0c;通过网络中节点之间的信息传递的方式来获取图中的依存关系&#xff0c;GNN通过从节点任意深度的邻居来更新该节点状态&#xff0c;这个状态能够表示状态信息。第一次在论文 The graph neural network model 中提出 与传统NN的区别&a…

UnsupportedOperationException深层探究

在调试程序的时候发现一个奇怪的问题&#xff0c;代码都是写过的很常见的代码&#xff0c;但是看日志会报错&#xff0c;报错信息如下&#xff1a;Exception in thread "main" java.lang.UnsupportedOperationExceptionat java.util.AbstractList.set(AbstractList.j…

mysql last lesson

1:创建用户 create user zhang identified by 12345678;2&#xff1a;给用户授权&#xff0c;撤销授权&#xff0c; grant.......to revoke ....... 3:将数据库中的数据导出 C:\Windows\system32>mysqldump bjpowernode>C:\bjpowernode.sql -uroot -p12345678 4&#…

nginx-ingress部署+跨命名空间转发

nginx-ingress部署一、环境信息二、k8s环境搭建三、ingress环境搭建3.1 deploy.yaml文件3.2 service-nodeport.yaml文件四、按照业务建立service及ingress4.1 业务信息4.2 建立service4.3 创建ingress五、验证结果一、环境信息 k8s集群版本&#xff1a;1.23.6ingress版本&…

MySQL高级三

目录 三、MySQL高级03 3.1 MyCat 3.1.1 MyCat简介 3.1.2 中间件的作用 3.2 安装MyCat 3.3 主从复制 3.3.1 主从复制的原理 3.3.2 主从复制的好处 3.3.3 配置主从复制 三、MySQL高级03 如果虚拟机的磁盘已满&#xff0c;可以对磁盘进行重新分配 参考&#xff1a;虚拟…

将IDEA的项目托管到gitee

目录1. 在gitee上创建仓库2. 本地创建仓库目录3. 将项目添加到缓冲区4. 将缓冲区的项目添加到本地仓库5. 将本地仓库的项目上传到gitee6. 遇到的问题6.1 问题描述6.2 解决方法7. 相关图示与补充8. 相关参考1. 在gitee上创建仓库 2. 本地创建仓库目录 在IDEA中选择创建 Git 仓…

命令行和Python交互模式

命令行和Python交互模式的区别 命令行模式mac打开终端 在命令行模式下&#xff0c;可以执行python进入Python交互式环境&#xff0c;也可以执行python hello.py运行一个.py文件。 执行一个.py文件只能在命令行模式执行 Python交互模式键入python3即可&#xff0c;交互模式下可…

centos安装gitlab

更新系统 sudo yum -y update安装所需要的包 sudo yum -y install epel-release curl vim policycoreutils-python如果要安装并使用本地Postfix服务器发送通知&#xff0c;请安装Postfix&#xff0c;这里就不安装了&#xff1a; sudo yum -y install postfix安装后启动并启用…

JVM虚拟机概述(2)

3.JVM 运行时数据区 3.1.1 程序计数器&#xff08;Program Counter Register&#xff09; 是一块很小的内存空间,用来记录每个线程运行的指令位置&#xff0c;是线程私有的,每个线程都拥有一个程序计数器&#xff0c;生命周期与线程一致&#xff0c;是运行时数据区中唯一一个不…

高压放大器知识科普介绍

高压放大器是一种用于放大高压信号的电子设备&#xff0c;具有高压输出&#xff0c;低噪声&#xff0c;高精度&#xff0c;高稳定性&#xff0c;高可靠性&#xff0c;低功耗&#xff0c;低成本等的优点&#xff0c;所以才被广泛应用在磁场探测、电磁脉冲放大、电磁波放大、电磁…

集成RocketChat至现有的.Net项目中,为ChatGPT铺路

文章目录前言项目搭建后端前端代理账号鉴权方式介绍登录校验模块前端鉴权方式后端鉴权方式登录委托使用登录委托处理聊天消息前端鉴权方式后端校验方式项目地址前言 今天我们来聊一聊一个Paas的方案&#xff0c;如何集成到一个既有的项目中。 以其中一个需求为例子&#xff1a…

使用Vue展示数据(动态查询)

学习内容来源&#xff1a;视频P4 本篇文章进度接着之前的文章进行续写 精简前后端分离项目搭建 Vue基础容器使用 目录选择组件修改表格组件修改分页组件增加后端接口前端请求数据接口页面初始化请求数据点击页码请求数据选择组件 在官方文档中选择现成的组件&#xff0c;放在页…

大数据技术——概述

根据IBM前首席执行官郭士纳的观点&#xff0c;IT领域每隔十五年就会迎来一次重大变革三次信息化浪潮1.存储设备容量不断增加2.CPU处理能力大幅提升3.网络带宽不断增加运营式系统阶段数据库的出现使得数据管理的复杂度大大降低,数据往往伴随着一定的运营活动而产生并记录在数据库…

手把手搭建springboot项目06-springboot整合RabbitMQ及其原理和应用场景

目录前言工作流程-灵魂画手名词解释交换机类型一、安装1.1 [RabbitMQ官网安装](https://www.rabbitmq.com/download.html)1.2 Docker安装并启动二、食用教程2.1.导入依赖2.2 添加配置2.3 代码实现2.3.1 直连&#xff08;Direct&#xff09;类型2.3.2 引入消息手动确认机制2.3.2…

【保姆级】Java后端查询数据库结果导出xlsx文件+打印xlsx表格

目录前言一、需求一&#xff1a;数据库查询的数据导出成Excel表格1.1 Vue前端实现导出按钮点击事件1.2 后端根据数据库查询结果生成xlsx文件二、需求二&#xff1a;对生成的xlsx文件调用打印机打印2.1 Vue前端实现按钮事件2.2 后端实现打印前言 最近在弄一个需求&#xff0c;需…