【手撕数据结构】(三)顺序表和链表

在这里插入图片描述

文章目录

  • 一、线性表
  • 二、顺序表
    • 1.概念及结构
    • 2.关于数组
    • 3.顺序表分类
      • 🎗️静态顺序表
      • 🎗️动态顺序表
    • 4.接口实现
      • (1)思路
      • (2)SeqList.h文件代码
        • 功能1:顺序表初始化
        • 功能2:销毁顺序表
        • 功能3:尾插
        • 功能4:头插
        • 功能5:尾删
        • 功能6:头删
        • 功能7:打印
        • 功能8:在pos位置处插入数据
        • 功能9:在pos位置处删除数据
        • 功能10:查找,找到返回下标,没有找到返回-1
        • 功能11:修改pos位置处的值
        • 完整代码展示
      • (3)SeqList.c文件代码
        • 实现功能1:顺序表初始化
        • 实现功能2:销毁顺序表
        • 实现功能3:尾插
        • 辅助功能:检查容量
        • 实现功能4:头插
        • 实现功能5:尾删
        • 实现功能6:头删
        • 实现功能7:打印
        • 实现功能8:在pos位置处插入数据
          • 复写功能:复用SLInsert重写头插、尾插
        • 实现功能9:在pos位置处删除数据
          • 复写功能:复用SLErase覆写头删、尾删![在这里插入图片描述](https://img-blog.csdnimg.cn/bffdab83cc2443019728ed16801b0578.png)
        • 实现功能10:查找
        • 实现功能11:修改pos位置处的值
        • 完整代码
      • (4)test.c文件代码
        • 测试1:尾插
        • 测试2:头插
        • 测试3:尾删
        • 测试4:头删
        • 测试5:pos位置处插入
        • 测试6:pos位置处删除
        • 测试7:查找
        • 测试8:如果有人传进来空指针怎么办?
  • 总结

一、线性表

🎗️线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
🎗️线性表在逻辑上是线性结构,也就说是一条连续的直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
在这里插入图片描述

二、顺序表

1.概念及结构

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

顺序表的本质是一个数组;要求数据必须从前往后连续存储。

2.关于数组

(1)数组怎么管理?

指针指向数组开始的位置,就能找到后面的位置。

(2)数组的缺陷

数组删除数据时,不能把数据所在的这块空间释放掉,只能把这一片数组空间都释放掉。数组删除元素的方式是挪动覆盖。

(3)数组的优势

下标的随机访问(原因是数组的物理空间连续)
a[i]等价于*(a+i)

(4)怎样弥补数组的缺陷

用链表。链表是一块一块的小空间,不是一个完整的连续空间。
如果有一个指针指向链表的第一个位置,不能找到后面的位置。因为他们是一块一块独立的空间,是多次malloc出来的,它们之间在地址上是没有关联的。
要想找到下一个位置,就得在上一个位置处存一个指针,指针指向下一个地址。
在这里插入图片描述
(二分查找不能在链表中使用,能在数组中使用;
排序不能在链表中使用,能在数组中使用)

3.顺序表分类

🎗️静态顺序表

使用定长数组存储元素。

#define N 7
typedef int SLDataType;
typedef struct SeqList {
	SLDataType array[N];  //定长数组
	int size;     //有效数据的个数
}SeqList;

在这里插入图片描述
总结:
静态顺序表缺点:空间是固定的,给小了不够用,给多了浪费

🎗️动态顺序表

使用动态开辟的数组存储。

typedef int SLDataType;
typedef struct SeqList {
	SLDataType* array;  //指向动态开辟的数组
	int size;  //存储的有效数据个数(知道什么时候扩容)
	int capacity;  //容量空间的大小
};

在这里插入图片描述

4.接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本上都是使用动态顺序表,根据需要动态的分配空间大小,所以我们下面实现动态顺序表。

(1)思路

建立三个文件
SeqList.c写接口的实现
SeqList.h写接口的声明
test.c写调用测试接口

(2)SeqList.h文件代码

首先,在里面定义动态顺序表的结构体
在这里插入图片描述

功能1:顺序表初始化

在这里插入图片描述

🎗️注意:在形参部分不要写成下面这样:
在这里插入图片描述
如果写成这样,就会出现经典的传值传参问题。此时,传过去的是值,实参传给形参,是一种拷贝。把s传给形参sl,形参sl变量的改变不会影响实参s,因为他们是在两个栈帧里面。
所以不要传结构体的值,而要传结构体的地址。

功能2:销毁顺序表

在这里插入图片描述

功能3:尾插

在这里插入图片描述

功能4:头插

在这里插入图片描述

功能5:尾删

在这里插入图片描述

功能6:头删

在这里插入图片描述

功能7:打印

在这里插入图片描述

功能8:在pos位置处插入数据

在这里插入图片描述

功能9:在pos位置处删除数据

在这里插入图片描述

功能10:查找,找到返回下标,没有找到返回-1

在这里插入图片描述

功能11:修改pos位置处的值

在这里插入图片描述

完整代码展示
#define _CRT_SECURE_NO_WARNINGS 1

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


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

void SLInit(SL* psl);//顺序表初始化
void SlDestroy(SL* psl);//销毁顺序表
void SLPushBack(SL* psl, SLDataType x);//尾插
void SLPushFront(SL* psl, SLDataType x);//头插
void SLPopBack(SL* psl);//尾删
void SLPopFront(SL* psl);//头删
void SLPrint(SL* psl);//打印
void SLInsert(SL* psl, int pos, SLDataType x); //在pos位置处插入数据
void SLErase(SL* psl, int pos);  //在pos位置处删除数据(也经常写作SLRemove)
int SLFind(SL* psl, SLDataType x);  //查找,找到返回下标,没有找到返回-1
void SLModify(SL* psl, int pos, SLDataType x); //修改pos下标位置的值


(3)SeqList.c文件代码

实现功能1:顺序表初始化

在这里插入图片描述

实现功能2:销毁顺序表

在这里插入图片描述

实现功能3:尾插

在这里插入图片描述

辅助功能:检查容量

在这里插入图片描述

实现功能4:头插

在这里插入图片描述

实现功能5:尾删

在这里插入图片描述

实现功能6:头删

在这里插入图片描述
在这里插入图片描述

实现功能7:打印

在这里插入图片描述

实现功能8:在pos位置处插入数据

在这里插入图片描述
在这里插入图片描述

复写功能:复用SLInsert重写头插、尾插

在这里插入图片描述

实现功能9:在pos位置处删除数据

在这里插入图片描述
在这里插入图片描述

复写功能:复用SLErase覆写头删、尾删在这里插入图片描述
实现功能10:查找

在这里插入图片描述

实现功能11:修改pos位置处的值

在这里插入图片描述

完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

//顺序表初始化
void SLInit(SL* psl) {
	assert(psl);//断言,判断传进来的指针不是空指针,避免后续对空指针解引用出错
	psl->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//在初始化的时候,最好的写法是一开始就开辟一点空间,开四个(不长也不短,是一个合适的数字)
	if (psl->a == NULL) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
		perror("malloc fail"); 
		return;
	}
	psl->size = 0;
	psl->capacity = 4;
}

//销毁顺序表---意思是把空间还给操作系统,像退房一样
void SLDestroy(SL* psl) {
	assert(psl);
	free(psl->a);
	psl->a = NULL;
	
	psl->size = 0;
	psl->capacity = 0;
}

//尾插
void SLPushBack(SL* psl, SLDataType x) {
	assert(psl);
	psl->a[psl->size] = x;
	psl->size++;
}

//检查容量
void SLCheckCapacity(SL* psl) {
	assert(psl);
	if (psl->size == psl->capacity) {
		SLDataType* tmp = (SLDataType*)realloc(psl->a, sizeof(SLDataType) * psl->capacity * 2);
		if (tmp == NULL) {
			perror("realloc fail");
			return;
		}
		psl->a = tmp;
		psl->capacity *= 2;
	}
}

//打印
void SLPrint(SL* psl) {
	assert(psl);
	for (int i = 0; i < psl->size; i++) {
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

//头插
void SLPushFront(SL* psl, SLDataType x) {
	assert(psl);
	SLCheckCapacity(psl);

	//挪动数据
	int end = psl->size - 1;
	while (end >= 0) {
		psl->a[end + 1] = psl->a[end];
		--end;
	}
	psl->a[0] = x;
	psl->size++;
}

//由在pos位置插入数据的功能函数重写头插、尾插,复用SLInsert
//void SLPushFront(SL* psl, SLDataType x) {
//	SLInsert(psl, 0, x);
//}
//void SLPushBack(SL* psl, SLDataType x) {
//	SLInsert(psl, psl->size, x);
//}

//尾删
void SLPopBack(SL* psl) {
	assert(psl);
	/*
	顺序表为空时,就不要再删了
	温柔的检查
	if (psl->size == 0) {
		return 0;
	}
	暴力检查(推荐):断言,如果psl->size>0为真就通过了,如果为假就会报错
	assert(psl->size > 0);
	*/
	
	//暴力检查(推荐)
	assert(psl->size > 0);


	//psl->a[psl->size-1]=0;
	//注意这样写不好,万一最后一个位置是0,这样做没意义,如果在数组中的元素类型是double,如今改为0不好,最好改为0.0
	//所以最好的做法是不管尾部数据是多少,只修改顺序表的长度size(有效数据个数)

	psl->size--;
}

//头删
void SLPopFront(SL* psl) {
	assert(psl);
	//暴力检查顺序表是不是为空
	assert(psl->size);

	//把下标start+1的元素挪给下标start处
	int start = 0; 
	while (start < psl->size - 1) {
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	

	/*
	start为1时,将下标start的元素挪给下标start-1处
	int start = 1;
	while (start < psl->size) {
		psl->a[start - 1] = psl->a[start];
		start++;
	}
	*/

	psl->size--;
	
}

//在pos位置处插入数据
void SLInsert(SL* psl,int pos, SLDataType x) {
	assert(psl);
	assert(0 <= pos && pos <= psl->size); //断言pos,不要让插入的位置下标越界

	SLCheckCapacity(psl);  //只要是插入数据,都要关注容量
	int end = psl->size - 1;
	while (end >= pos) {
		psl->a[end + 1] = psl->a[end];
		--end;
	}
	psl->a[pos] = x;
	psl->size++;
}


//在pos位置处删除数据
void SLErase(SL* psl, int pos){
	assert(psl);
	assert(0 <= pos && pos < psl->size); //注意这里的pos不能等于psl->size
	//assert(psl->size>0);  这句代码是用来断言有效数据个数为不为空,为空时不用删,但是这句代码加不加都行,因为上一句已经间接检查了

	int start = pos + 1;
	while (start < psl->size) {
		psl->a[start - 1] = psl->a[start];
		++start;
	}
	psl->size--;
}

//复用SLErase覆写头删、尾删
//void SLPopFront(SL* psl) {
//	SLErase(psl, 0);
//}
//void SLPopBack(SL* psl) {
//	SLErase(psl, psl->size - 1);
//}


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

//修改
void SLModify(SL* psl, int pos,SLDataType x) {
	assert(psl);
	assert(0 <= pos && pos < psl->size);

	psl->a[pos] = x;
}

(4)test.c文件代码

测试1:尾插

在这里插入图片描述
在这里插入图片描述

测试2:头插

在这里插入图片描述
在这里插入图片描述

测试3:尾删

在这里插入图片描述
在这里插入图片描述

测试4:头删

在这里插入图片描述
在这里插入图片描述

测试5:pos位置处插入

在这里插入图片描述
在这里插入图片描述

测试6:pos位置处删除

在这里插入图片描述
在这里插入图片描述

测试7:查找

在这里插入图片描述
在这里插入图片描述

测试8:如果有人传进来空指针怎么办?

在这里插入图片描述
在这里插入图片描述
所以说怎么办?

在每个函数内部做一下断言,暴力检查一下。暴力检查的好处是不用调试,出错时会出现错误提示。如下图:
在这里插入图片描述

为什么不在main函数中做断言?

写的函数才是给我们用的,不要在调用函数时去检查(也就是说让调用的人去检查,如果他会检查,就不会传空进来了)


总结

顺序表的内容就到这里啦~欢迎大家关注后续内容
👻

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

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

相关文章

QT基础学习

2创建项目 2.1使用向导创建 打开Qt Creator 界面选择 New Project或者选择菜单栏 【文件】-【新建文件或项目】菜单项 弹出New Project对话框&#xff0c;选择Qt Widgets Application&#xff0c; 选择【Choose】按钮&#xff0c;弹出如下对话框 设置项目名称和路径&#xf…

5分钟教你轻松搭建Web自动化测试框架

在程序员的世界中&#xff0c;一切重复性的工作&#xff0c;都应该通过程序自动执行。「自动化测试」就是一个最好的例子。 随着互联网应用开发周期越来越短&#xff0c;迭代速度越来越快&#xff0c;只会点点点&#xff0c;不懂开发的手工测试&#xff0c;已经无法满足如今的…

在网络攻击之前、期间和之后应采取的步骤

在当今复杂的威胁形势下&#xff0c;网络攻击是不可避免的。 恶意行为者变得越来越复杂&#xff0c;出于经济动机的攻击变得越来越普遍&#xff0c;并且每天都会发现新的恶意软件系列。 这使得对于各种规模和跨行业的组织来说&#xff0c;制定适当的攻击计划变得更加重要。 …

【Linux】指令详解(二)

目录 1. 前言2. 重新认识指令2.1 指令的本质2.1.1 which2.1.2 alias 3. 常见指令3.1 whoami3.2 cd3.2.1 cd -3.2.2 cd ~ 3.3 touch3.3.1 文件创建时间 3.4 stat3.5 mkdir3.5.1 创建一个目录3.5.2 创建路径 3.6 tree3.7 rm3.7.1 rm -f3.7.2 rm -r 3.8 man3.9 cp3.10 mv 1. 前言 …

【洛谷 P3743】kotori的设备 题解(二分答案+递归)

kotori的设备 题目背景 kotori 有 n n n 个可同时使用的设备。 题目描述 第 i i i 个设备每秒消耗 a i a_i ai​ 个单位能量。能量的使用是连续的&#xff0c;也就是说能量不是某时刻突然消耗的&#xff0c;而是匀速消耗。也就是说&#xff0c;对于任意实数&#xff0c;…

【Unity】万人同屏高级篇, 自定义BRGdots合批渲染,海量物体目标搜索

Unity万人同屏海量物体合批渲染 Unity万人同屏海量物体目标搜索 Unity万人同屏手机端测试&#xff0c;AOT和HybridCLR热更性能对比 博文开发测试环境&#xff1a; Unity&#xff1a;Unity 2022.3.10f1&#xff0c;URP 14.0.8&#xff0c;Burst 1.8.8&#xff0c;Jobs 0.70.0-p…

Spring Boot - 自定义注解来记录访问路径以及访问信息,并将记录存储到MySQL

1、准备阶段 application.properties&#xff1b;yml 可通过yaml<互转>properties spring.datasource.urljdbc:mysql://localhost:3306/study_annotate spring.datasource.usernameroot spring.datasource.password123321 spring.datasource.driver-class-namecom.mysq…

Mybatis系列之 parameterMap 弃用了

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; &#x1f383; 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 &#x1f3f7;️ 标签 | 男 自律狂人 目标明确 责任心强 ✈️公…

Java八股文(急速版)

Redis八股文 我看你在做项目的时候都使用到redis&#xff0c;你在最近的项目中哪些场景下使用redis呢? 缓存和分布式锁都有使用到。 问&#xff1a;说说在缓存方面使用 1.在我最写的物流项目中就使用redis作为缓存&#xff0c;当然在业务中还是比较复杂的。 2.在物流信息…

创新工具 | 教你6步用故事板设计用户体验事半功倍

问题 构思方案时团队在细节上难以共识 故事板是什么&#xff1f;故事板就像连环画一样&#xff0c;将用户使用解决方案的关键步骤顺序串联了起来&#xff0c;呈现了方案和用户之间的交互。 故事板以先后顺序展现团队票选出来的最佳解决方案&#xff0c;在过程中对于方案中未…

几个强力的nodejs库

几个强力的nodejs库 nodejs被视为许多Web开发人员的理想运行时环境。 nodejs的设计是为了在运行时中使用JavaScript编写的代码&#xff0c;它是世界上最流行的编程语言之一&#xff0c;并允许广泛的开发者社区构建服务器端应用程序。 nodejs提供了通过JavaScript库重用代码的…

Linux--网络编程

一、网络编程概述1.进程间通信&#xff1a; 1&#xff09;进程间通信的方式有**&#xff1a;管道&#xff0c;消息队列&#xff0c;共享内存&#xff0c;信号&#xff0c;信号量这么集中 2&#xff09;特点&#xff1a;依赖于linux内核&#xff0c;基本是通过内核来实现应用层…

计算机毕业设计选题推荐-家庭理财微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

SVG圆形 <circle>的示例代码

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

腾讯云助力港华能源上线“碳汭星云2.0”,推动能源行业绿色低碳转型

11月17日&#xff0c;港华能源与腾讯云联合打造的港华智慧能源生态平台“碳汭星云2.0”升级上线。依托双方的连接、大数据能力和行业深耕经验&#xff0c;该平台打破了园区“数据孤岛”&#xff0c;进一步提升了数据治理、应用集成和复制推广能力&#xff0c;未来有望以综合能源…

Docker发布简单springboot项目

Docker发布简单springboot项目 在IDEA工具中直接编写Dockerfile文件 FROM java:8COPY *.jar /app.jarCMD ["--server.prot 8080"]EXPOSE 8080ENTRYPOINT ["java", "-jar", "/app.jar"]将项目打包成对应的jar包&#xff0c;将Dockerf…

html主页框架,前端首页通用架构,layui主页架构框架,首页框架模板

html主页框架 前言功能说明效果使用初始化配置菜单加载主题修改回调 其他非iframe页面内容使用方式iframe页面内容使用方式 前言 这是一个基于layui、jquery实现的html主页架构 平时写的系统后台可以直接套用此框架 由本人整合编写实现&#xff0c;简单上手&#xff0c;完全免…

Android WMS——输入系统管理(十七)

一、简介 1、工作原理 输入子系统从驱动文件中读取事件后,再封装提交给 IMS,IMS 再发送给 WMS 进行处理。 Android 输入系统的工作原理概括来说,内核将原始事件写入到设备节点中,InputReader 不断地通过 EventHub 将原始事件取出来并翻译加工成 Android 输入事件,…

计算机网络(持续更新…)

文章目录 一、概述1. 计网概述⭐ 发展史⭐ 基本概念⭐ 分类⭐ 数据交换方式&#x1f970; 小练 2. 分层体系结构⭐ OSI 参考模型⭐TCP/IP 参考模型&#x1f970; 小练 二、物理层1. 物理层概述⭐ 四个特性 2. 通信基础⭐ 重点概念⭐ 极限数据传输率⭐ 信道复用技术&#x1f389…

C++:拷贝构造函数,深拷贝,浅拷贝

一.什么是拷贝构造函数&#xff1f; 同一个类的对象在内存中有完全相同的结构&#xff0c;如果作为一个整体进行复制&#xff08;拷贝&#xff09;是完全可行的。这个拷贝过程只需要拷贝数据成员&#xff0c;而函数成员是共用的&#xff08;只有一份拷贝&#xff09;。在建立对…