线性数据结构集会

news2024/11/20 2:47:07

目录

序言

一、数组

数组的优点

数组的缺点

数组的适用场景

二、链表

链表的优点

链表的缺点

链表的使用场景

链表的种类

Java单向链表的实现

三、队列

队列的特点

四、栈

栈的特点

栈的适用场景

五、时间复杂度简述


序言

        线性数据结构是一种将数据元素以线性的方式组织和存储的数据结构。线性数据结构中的元素按顺序排列,每个元素最多只有一个前驱和一个后继。

常见的线性数据结构包括:

  • 数组(Array):连续存储相同类型的元素,通过索引直接访问。
  • 链表(Linked List):通过指针连接的节点组成,每个节点包含数据和指向下一个节点的指针。
  • 栈(Stack):具有先进后出(LIFO)特性,只能在栈顶进行插入和删除操作。
  • 队列(Queue):具有先进先出(FIFO)特性,只能在队尾进行插入,在队头进行删除。

一、数组

        数组用于存储一组相同类型的元素。它是由连续的内存空间组成的,每个元素都有唯一的索引,使得可以通过索引访问和修改数组中的元素。

数组的优点

  1. 支持随机访问,因为数组的每个元素都有唯一索引;
  2. 占用内存较少,因为数组的元素连续存储,不需要额外的指针连接节点或元素之间的关系。
  3. 已知下标的插入删除可以快速精准定位

数组的缺点

  1. 当需要存储元素数量变化较大的情况时,需要重新分配更大的数组并进行数据复制,会造成一定的损失。
  2. 插入和删除效率低。对于需要在数组中间或开头插入或删除元素的操作,需要移动大量元素来保持连续性,造成插入和删除效率较低。
  3. 容易造成空间的浪费。

数组的适用场景

  1. 读多,修改少的时候
  2. 存储元素数量(长度)固定,数据变动很小的时候
  3. 需要存储简单且数量较小的数据的时候
  4. 通过数组顺序实现其他复杂数据结构的时候

二、链表

        链表是由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表中的节点可以在内存中分散存储,彼此通过指针连接起来。

每个节点由两个主要部分组成:

  1. 数据:节点中存储的数据,可以是任意类型,根据具体需求而定。
  2. 指针:指向下一个节点的指针,通常称为"next"指针。它存储了下一个节点在内存中的地址或引用。

        链表的第一个节点称为头节点,最后一个节点称为尾节点。尾节点的指针通常为null或空,表示链表的结束。

链表的优点

  1. 链表是通过指针的指向来实现线性连接的,不受固定大小的限制,空间利用率高。
  2. 插入和删除操作效率高,只需要修改前驱和后继节点的指向
  3. 灵活性高,适用于那些需要频繁修改结构的场景。

链表的缺点

  1. 查询效率低,因为它不能精准查询,需要遍历链表
  2. 内存消耗较高,一个节点不仅要存储数据本身,还要存储节点关系
  3. 存储不连续,无法充分利用缓存。

链表的使用场景

  1. 数据插入和删除频繁的场景
  2. 数据规模不确定的场景
  3. 通过链表链式实现其他复杂数据结构,比如树的链式存储。

链表的种类

链表的种类概述
链表类型链表特点

单向链表(Singly Linked List):每个节点包含一个指向下一个节点的指针。它是最简单的链表类型,适用于顺序访问以及插入和删除操作频繁的场景。

  • 每个节点只包含一个指向下一个节点的指针。
  • 可以顺序访问节点。
  • 插入和删除操作的效率较高。
  • 查找某个节点的效率较低,需要从头节点开始逐一向后遍历

双向链表(Doubly Linked List):每个节点包含一个指向下一个节点和一个指向前一个节点的指针。相比单向链表,双向链表可以双向访问,方便在某个节点之前或之后插入或删除节点。

  • 每个节点包含一个指向下一个节点和一个指向前一个节点的指针。
  • 可以双向访问节点,不仅可以从头到尾遍历,还可以从尾到头遍历。
  • 插入和删除操作更加灵活,可以在某个节点之前或之后插入或删除节点。
  • 链表的结构相对复杂,需要额外的指针来维护前后节点的关系。

循环链表(Circular Linked List):和单向链表或双向链表类似,不同之处在于最后一个节点的指针指向第一个节点,形成一个循环。循环链表的一个优点是在操作时更容易处理边界情况,因为没有"尾部"节点。

  • 和单向链表或双向链表类似,最后一个节点的指针指向第一个节点,形成一个循环。
  • 可以用于处理环形相关问题,比如判断链表中是否存在环。
  • 需要额外注意循环的终止条件,以防止陷入无限循环。

跳表(Skip List):跳表是一种有序链表的扩展,通过在不同层级上添加额外的指针,使得搜索的效率更高。跳表可以用于需要高效搜索和插入操作的场景,比如有序集合的实现。

  • 是一种有序链表的扩展,通过在不同层级上添加额外的指针,提高搜索的效率。
  • 可以用于高效的搜索和插入操作,适用于需要快速定位的有序集合场景。
  • 需要额外的空间来维护层级指针,占用较多的存储空间。

Java单向链表的实现

package com.csq;

import java.util.StringJoiner;

import com.practice.SingleLinked.Node;

// 链表类
public class Linked<E> {
	
	// 头结点
	private Node<E> first;
		
	// 尾节点
	private Node<E> last;
	
	// 头插法
	public void addFirst(E item) {
		// 新节点
		final Node<E> newNode = new Node<E>(item);
		// 保存原来的头节点
		final Node<E> f = first;
		// 新的节点变成新的头节点
		first = newNode;
		// 如果原头节点不为空,即链表不为空
		if(f != null) {
			// 新头节点的下一个节点指向原头节点
			newNode.next = f;
		}else {
			// 如果链表为空,新节点既是头节点也是尾节点
			last = newNode;
		}
		
	}
	
	// 尾插法
	public void addLast(E item) {
		// 创建新节点
		final Node<E> newNode = new Node<E>(item);
		// 保存原来的尾节点
		final Node<E> l = last;
		// 新节点变为新的尾节点
		last = newNode;
		// 链表为空
		if(l == null) {
			// 既是头节点也是尾节点
			first = newNode;
		}else {
			l.next = newNode;
		}
		
	}
	
	//获取链表长度
	public int size() {
		int size = 0;
		for (Node<E> x = first; x != null; x = x.next) {
			size++;
		}
		return size;
	}

	// 重写toString()输出链表结果
	@Override
	public String toString() {
		/* StringJoiner类是用于拼接字符串的辅助类。
		 * 用于将多个字符串按照指定的分隔符连接起来,生成一个新的字符串。*/
		StringJoiner sj = new StringJoiner("->");
		for(Node<E> n = first; n!= null;n=n.next) {
			sj.add(n.item.toString());
		}
		return sj.toString();
	}
	
	// 单向链表的节点
	public static class Node<E>{
		E item; // 数据域
		Node<E> next; // 后继节点(指针域)
		public Node(E data) {
		    this.item = data;
		}
	}
}

三、队列

队列是一种常见的数据结构,它按照先进先出(FIFO)的原则管理数据。队列有两个基本操作:入队(enqueue)和出队(dequeue)。

队列可以简单地定义为具有以下属性的数据集合:

  1. 队尾(rear):用于插入新元素的位置。
  2. 队头(front):用于删除元素的位置,也是队列中最早插入的元素。

当元素按顺序插入队列时,它们按照先进先出的顺序删除。新元素始终插入队列的队尾,而删除操作始终在队头进行。

队列可以使用数组或链表实现。数组实现的队列称为顺序队列,链表实现的队列称为链式队列。

队列的特点

  1. 先进先出(FIFO):队列按照元素的插入顺序进行处理,保证了先进入队列的元素先被处理。
  2. 顺序性:队列可以维护元素的顺序,适用于那些需要按照特定顺序进行处理的场景。
  3. 简单高效:队列的插入和删除操作只涉及到队头和队尾,具有较高的执行效率。

队列适用于需要按照先进先出顺序处理任务、保持顺序性、实现并发和协作等场景。

四、栈

        栈(Stack)是一种具有特定操作规则的线性数据结构,它按照后进先出(Last-In-First-Out,LIFO)的原则进行操作。栈可以看作是一种受限制的线性表,只允许在表的一端进行插入和删除操作,这一端被称为栈顶,另一端称为栈底。

栈的定义可以用以下几个要点来描述:

  1. 数据存储:栈中的元素按照一定的顺序存储,通常使用数组或链表来实现。
  2. 后进先出:栈的特点是在进行插入(压栈)和删除(弹栈)操作时,最后一个插入的元素首先被删除。
  3. 只操作栈顶:栈的操作限制只能在栈顶进行,也即只允许从栈顶插入和删除元素。
  4. 是一个有限容量的容器:存储元素的数量有限,当栈满时无法再插入新的元素。栈空时,无法弹出元素。

在栈中,插入新的元素(压栈)会将元素放置在当前栈顶上方,而删除元素(弹栈)会将栈顶元素移除并返回该元素。此外,栈还提供了一个方法用于读取当前栈顶元素的值,而不对栈进行修改。

栈的特点

  1. 后进先出(Last-In-First-Out,LIFO):栈的操作原则是先插入的元素将最后一个被删除。也就是说,最后压入(插入)栈的元素将成为下一个弹出(删除)的元素。

  2. 只操作栈顶:栈操作只涉及栈顶元素的插入、删除和读取,不允许直接访问或修改栈中的其他元素。

  3. 有限容量:栈的容量是有限的,即在一个栈中可以存储的元素数量是有限的。

  4. 快速插入和删除:由于栈的特性,插入(压栈)和删除(弹栈)操作都只需在栈顶进行,时间复杂度为 O(1)。这使得栈在对数据进行临时存储和后续操作时非常高效。

  5. 存储顺序:栈中的元素按照插入顺序存储,后插入的元素位于较早插入的元素之上。栈的顶部视为最新插入的元素,栈底视为最早插入的元素。

栈的适用场景

栈适用于需要后进先出(LIFO)特性的场景,比如以下几种场景

  • 函数调用

  • 表达式求值

  • 括号匹配

  • 浏览器的前进后退

  • 深度优先搜索(DFS)

五、时间复杂度简述

数组:

  • 查找的时间复杂度O(1) ,因为可以通过下标精准定位
  • 插入和删除时间复杂度为 O(n),因为需要移动其他元素

链表:

  • 查找的时间复杂度O(n),因为需要遍历
  • 插入和删除的时间复杂度为 O(1),因为只需调整相邻节点的指针

队列:

  • 入队和出队的时间复杂度都是 O(1),因为只需修改队头或队尾的指针
  • 查找的时间复杂度为 O(n),因为需要遍历

栈:

  • 入栈和出栈的时间复杂度都是 O(1),因为只需修改栈顶指针
  • 查找的时间复杂度为 O(n),因为需要遍历

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

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

相关文章

C语言,洛谷题:你的飞碟在这

文中要把字母A对应到1&#xff0c;Z对应到26&#xff0c;这时候就要用上ASCII表了。A对应的ASCII码值是65&#xff0c;要让A对应1&#xff0c;只要将A减去64&#xff0c;后面的字母也是一样的只要减去64&#xff0c;就能对应其26字母中的顺序。 要存储字符串对应的每个元素的数…

计算机毕业设计选什么题目好?springboot 学生考勤管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Java实验一 Java语言基础(12题)

文章目录&#xff1a; 1、我国历法中的天干、地支和生肖的排列是有规律的。天干的顺序是“甲乙丙丁戊己庚辛壬癸”&#xff0c;地支的顺序是“子丑寅卯辰巳午未申酉戌亥”&#xff0c;生肖的顺序是“鼠牛虎兔龙蛇马羊猴鸡狗猪”。天干、地支、生肖的计算方法非常简单&#xff…

Etsy玩家必看之7个运营技巧

2023年跨境电商行业趋势愈发旺盛&#xff0c;目前正处于红利期&#xff0c;而作为近年来的电商网红“Etsy”&#xff0c;以其低成本低竞争高回报的优势吸引了大批的跨境电商玩家。但仅仅入驻照搬其他平台经验很难出单&#xff0c;如果你正烦恼这个问题&#xff0c;那么接下来的…

软件测试学习(一)基础概念、实质、说明书测试、分类、动态黑盒测试

软件测试概念、背景 软件无处不在。然而&#xff0c;软件是人写的一所以不完美。 世界上有完美的软件吗&#xff1f;NO 世界上没有完美的软件。所有软件都可能存在缺陷、错误或漏洞&#xff0c;无论是操作系统、应用程序、游戏还是其他类型的软件。这些问题可能会导致功能问题…

1.软件开发-HTML结构-元素剖析

元素的嵌套 代码注释 ctrl/ URL url 统一资源定位符 一个给定的独特资源在web上的地址 URI

那些年,我们一起发现的Bug

一、背景 在这篇文章中&#xff0c;分享一些自己在工作中或别人发现的一些常见Bug&#xff0c;与大家共同成长~ 二、常见Bug分类 1、前后命名不一致 举个例子 接口入参中的名称是&#xff1a;aslrboot Java代码中使用的名称是&#xff1a;aslrBoot Codis中存储的名称是&…

LCD简介

lcd简介 LCD简介1、分辨率2、像素格式3、LCD时间参数4、RGB LCD屏幕时序6、像素时钟 此文章摘抄于正点原子的嵌入式linux驱动开发指南&#xff0c;仅作为笔记&#xff0c;以放便忘记时查阅 LCD简介 LCD全称是Liquid Crystal Display,也就是液晶显示器&#xff0c;其显示的基本原…

机器人的组成

机器人是一个机电一体化的设备&#xff0c;从控制的角度来看&#xff0c;机器人系统可以分成四大部分&#xff0c;即执行机构、驱动系统、传感系统和控制系统. 各部分之间的控制关系如下图所示。 执行机构 执行机构是直接面向工作对象的机械装置&#xff0c;相当于人体的手和脚…

3年测试经验,测试用例应该达到这个水平才合格

状态迁移法主要关注在测试状态转移的正确性上面。对于一个有限状态机&#xff0c;通过测试验证其在给定的条件内是否能够产生需要的状态变化&#xff0c;有没有不可达的状态和非法的状态&#xff0c;是否可能产生非法的状态转移等。通过构造能导致状态迁移的事件&#xff0c;来…

力扣-2512.奖励最顶尖的k名学生

Idea 记录caibi学习的第n天&#xff0c;这道题折磨了我两个多小时&#xff0c;终于用自己的思路ac了 大佬建议参考官方题解思路 用一个map记录学生id及其得分情况 用两个set存放 正面词汇集和负面词汇集 遍历report&#xff0c;然后获取每一个单词&#xff0c;跟两个set进行查找…

二叉树链式结构的遍历访问——前中后序

最开始接触树的时候&#xff0c;因为并不是二叉树&#xff0c;所以我们并不知道一个节点最多有几个度&#xff0c;所以我们要用链表来实现树的话就需要用孩子兄弟法 然后我们认识了完全二叉树&#xff0c;因为它是从左到右都满的二叉树&#xff0c;所以我们可以用顺序表&#…

【数据结构】二叉树的顺序结构及实现

目录 1. 二叉树的顺序结构 2. 堆的概念及结构 3. 堆的实现 3.1 堆向下调整算法 3.2 堆的创建 3.3 建堆时间复杂度 3.4 堆的插入 3.5 堆的删除 3.6 堆的代码实现 4. 堆的应用 4.1 堆排序 4.2 TOP-K问题 1. 二叉树的顺序结构 普通的二叉树是不适合用数组来存储的&…

【算法-动态规划】贝尔曼福特算法

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

面试经典 150 题 2 —(双指针)— 392. 判断子序列

392. 判断子序列 方法一 class Solution { public:bool isSubsequence(string s, string t) {int top 0, bottom 0;int tlength t.length(), slength s.length();if(slength 0){return true;}while(top < tlength){if(s[bottom] t[top]){bottom;}if(bottom slength)…

C++DAY43

#include <iostream>using namespace std;//封装 沙发 类 class Sofa { private:string living; public:Sofa(){cout << "沙发的无参构造函数" << endl;}Sofa(string l):living(l){cout << "沙发的有参构造函数" << endl;}v…

创建一个基本的win32窗口

1.建立一个窗口的基本步骤 &#xff08;1&#xff09;向系统注册一个窗体类 &#xff08;2&#xff09;根据窗体类创建窗口 &#xff08;3&#xff09;进入消息循环 2.程序结构 (1)主函数的输入参数 int WINAPI WinMain( HISTANCE hInstance,//当前窗口的句柄 HINSTANCE hPr…

10.9~10.10

触发器方程 触发器之间的转化 触发器需要输入和输出 对于D触发器&#xff0c;只需要D信号的输入 对于jk触发器&#xff0c;至少需要原状态的与非信号&#xff0c;并且需要j,k信号 假如确定y2,则D触发器需要什么D信号&#xff0c;是需要卡诺图确定 j-k触发器需要什么jk信号…

NewStarCTF 2023 公开赛道 WEEK2|Crypto

目录 T1.滴啤 T2.不止一个pi T3.halfcandecode T4.Rotate Xor T5.broadcast T6.partial decrypt T1.滴啤 下载题目附件&#xff0c;我们获得到以下代码。 from Crypto.Util.number import * import gmpy2 from flag import flag def gen_prime(number):p getPrime(numb…

【java基础学习】之环境变量的配置

java环境变量的配置 第一步&#xff1a;打开电脑->属性->高级系统设置 第二步&#xff1a;点开环境变量 第三步&#xff1a;找到path&#xff08;windows系统执行命令时要搜寻的路径&#xff09; 将按照的bin路径放到新增到path下面&#xff1a; 运行cmd&#xff0c;然…