一文学懂数据结构系列之:顺序表

2024-06-22 08:32

本文主要是介绍一文学懂数据结构系列之:顺序表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成,愿将昔日所获与大家交流一二,希望对学习路上的你有所助益。同时,博主也想通过此次尝试打造一个完善的技术图书馆,任何与文章技术点有关的异常、错误、注意事项均会在末尾列出,欢迎大家通过各种方式提供素材。

  • 对于文章中出现的任何错误请大家批评指出,一定及时修改。
  • 有任何想要讨论和学习的问题可联系我:zhuyc@vip.163.com。
  • 发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。

一文学懂数据结构系列之:顺序表

本文关键字:数据结构、基本结构、线性表、顺序表、结构实现

文章目录

  • 一文学懂数据结构系列之:顺序表
    • 一、什么是数据结构
      • 1. 数据与数据结构
      • 2. 逻辑结构
      • 3. 存储结构
      • 4. 数据操作
    • 二、线性表
      • 1. 线性表介绍
      • 2. 顺序表
    • 三、结构实现
      • 1. 接口定义
      • 2. 功能实现
      • 3. 调用测试

一、什么是数据结构

本专栏为《手撕算法》栏目的子专栏:《数据结构》,会讲述一些基础及经典的数据结构,并对常规操作进行实现。在此之前需要先了解数据与结构之间的关系,各自有什么样的特点。

1. 数据与数据结构

  • 数据

数据是信息的载体,在计算机领域中,可以认为所有能够被输入到计算机,并且能够被计算机处理的符号都可以被称为数据。可以是字符串、音频、视频等各数据形式,本专栏主要讨论数值数据(结合各数据结构)。

  • 数据元素

数据元素就是数据中的每个个体,是组成数据(集合)的基本单位。有些时候数据元素当中包含的数据并不是单一的,所以我们可以把数据元素看成一条数据或是某个数据结构中的一个节点

  • 数据项

数据项就是数据元素的组成部分,是其中具体的细项。数据项可以分为简单数据项组合数据项两种,如姓名、年龄等不可再分割的描述属于简单数据项;对于日期等数据项还可以被分为更小的数据项,属于组合数据项。

  • 数据对象

数据对象是性质相同的数据元素的集合,通常作为要处理数据的统称,如:整数、正整数等,也可以是符合自定义规则的数据,如具有相同数据维度的数据表等。

  • 数据结构

数据结构可以用于刻画和描述数据元素之间的关系,如:线性、树形等。同时,也可以看做是符合一种或多种特定关系的数据元素的集合。

2. 逻辑结构

逻辑结构是用于描述各个数据元素之间的逻辑关系,主要描述数据元素的组织形式,包含元素间相邻的个数开始结点终端结点前驱后继等。其中:集合、树、图也可统称为非线性结构

  • 松散结构(集合)

如果数据元素之间除了属于同一个集合(即具备某个相同性质)外,再没有其他的关系,可以称这种关系为松散性的(不作为研究的重点)。

  • 线性结构

线性结构中的数据元素之间存在一对一关系。在非空情况下,有且仅有一个开始结点和终端结点。并且开始结点没有前驱,有一个后继;终端结点没有后继,但有一个前驱;其余结点有且仅有一个前驱和后继。

  • 树形结构

树形结构中的数据元素之间存在一对多关系。在非空情况下,有一个称为的结点,此结点无前驱结点;其余结点有且仅有一个前驱,但可以有多个后继(没有后继的结点称之为叶子结点)。

  • 图形结构

图形结构中的数据元素之间存在多对多关系。在非空情况下,任何结点都可能有多个前驱和多个后继。

3. 存储结构

数据的存储结构是数据的逻辑结构在计算机中的实现,说白了就是具体是如何存储的。由于在计算机中最小的数据表示单位是二进制位(一个bit),所以数据元素的值都是以二进制方式存储的(一个值可能会对应多个二进制位),而数据元素之间逻辑关系的表示主要有以下4种方式。

  • 顺序存储

顺序存储是将所有数据元素存放在一片连续的存储空间中,使逻辑上相邻的数据元素在物理位置上也相邻。

  • 链式存储

链式存储不要求逻辑上相邻的数据元素在存储时物理位置也相邻,可以存储在任意位置,但是需要由两部分组成:数据元素本身指针(用于记录相邻元素的位置)。

  • 索引存储

所以存储在存储元素的同时还增加了一个索引表。通常会在索引表中记录数据元素中的关键数据项的值,称为关键字(能够唯一标识数据元素),除此之外还会存储对应的存储地址(可以在按规则排序时使用)。

  • 散列存储

散列存储也称哈希存储。该方式将开辟一片连续的存储空间,在该区域中存储数据元素的关键字,存储的位置根据预先设定的哈希函数来计算。

4. 数据操作

数据操作就是对数据进行某种处理,以达到预期的效果,也被称为数据的运算。在确定了数据结构后,通常会对其中的数据元素进行如下操作:

  • 创建

对于数据结构的初始化操作,会根据预先定义好的结构创建出一个可操作的实例。

  • 销毁

将已创建出的存储结构进行回收,进行空间的释放(通常交由计算机控制,不作为研究重点)。

  • 插入

向数据结构中的某个位置上插入一个指定的新数据元素。

  • 删除

从数据结构中删除某个符合条件的数据元素,并保持数据结构的性质。

  • 查找

在数据结构中查找满足条件的数据元素。

  • 修改

修改数据结构中指定数据元素的值。

  • 遍历

对数据结构中的每一个数据元素按某种方式或路径访问一次,并且仅访问一次。

二、线性表

1. 线性表介绍

线性表是由n个数据元素构成的有限序列,其中n为线性表的长度,当n=0时,线性表为空表。线性表中的数据均是同一类型,并且数据元素之间具有线性一对一的逻辑关系。

  1. 第一个元素没有前驱,称为开始结点
  2. 最后一个元素没有后继,称为终端结点
  3. 其他元素有且仅有一个前驱后继
  • 顺序表

线性表的顺序存储:顺序存储的线性表,用一片地址连续的存储单元依次存放线性表中的各个数据元素。

  • 链表

线性表的链式存储:链式存储的线性表,链表中每一个结点包含数据域指针域两部分。其中数据域用于存放数据元素的值,指针域用于存放相邻元素的位置信息。

2. 顺序表

  1. 逻辑上相邻的元素,在物理存储上也相邻。
  2. 存储密度高,需要预先分配对应长度的空间。
  3. 便于随机存取,可以根据地址关系直接获取到对应位置的元素。
  4. 不利于插入和删除,为了保证线性关系,需要对其他元素进行串位。

三、结构实现

1. 接口定义

使用Java语言实现,在接口中先定义需要具备的功能(基于线性表):

/*** 线性表功能接口*/
public interface IList {/*** 将线性表置为空表*/public void clear();/*** 查看线性表是否为空* @return true:空 false:非空*/public boolean isEmpty();/*** 查看线性表长度* @return 当前数据元素个数*/public int length();/*** 返回指定位置上的数据元素,如果索引超出范围,则引发越界异常* @param i 索引位置* @return 对应位置的数据元素*/public Object get(int i);/*** 在指定位置之前插入一个数据元素,如果索引超出范围,则引发越界异常* @param i 索引位置* @param e 数据元素*/public void insert(int i, Object e) throws Exception;/*** 删除并返回对应位置上的数据元素,如果索引超出范围,则引发越界异常* @param i 索引位置* @return 数据元素*/public Object remove(int i) throws Exception;/*** 返回待查找数据元素在线性表中第一次出现的位置,若不存在返回-1* @param e 数据元素* @return 索引位置*/public int indexOf(Object e);/*** 遍历输出顺序表中的所有数据元素*/public void show();}

2. 功能实现

使用Java代码对线性表进行顺序存储实现,如下:

/*** 线性表的顺序存储实现:顺序表*/
public class SequenceList implements IList {private Object[] elements;// 线性表存储空间private int currentLength;// 线性表当前长度/*** 创建一个具有指定存储空间大小的顺序表* @param size 存储空间大小*/public SequenceList(int size){elements = new Object[size];currentLength = 0;// 线性表中最初数据元素为0}@Overridepublic void clear() {currentLength = 0;}@Overridepublic boolean isEmpty() {return currentLength == 0;}@Overridepublic int length() {return currentLength;}@Overridepublic Object get(int i) {if (i < 0 || i > currentLength - 1){throw new IndexOutOfBoundsException("索引下标越界");}return elements[i];}@Overridepublic void insert(int i, Object e) throws Exception {if (currentLength == elements.length){throw new Exception("当前顺序表已满");}if (i < 0 || i > currentLength){throw new IndexOutOfBoundsException("索引下标越界");}for (int j = currentLength; j > i; j--) {elements[j] = elements[j - 1];}elements[i] = e;currentLength++;}@Overridepublic Object remove(int i) {if (i < 0 || i > currentLength - 1){throw new IndexOutOfBoundsException("索引下标越界");}Object e = elements[i];for (int j = i; j < currentLength - 1; j++) {elements[j] = elements[j + 1];}currentLength--;return e;}@Overridepublic int indexOf(Object e) {int j = 0;while (j < currentLength && !elements[j].equals(e)){j++;}if (j < currentLength){return j;}else {return -1;}}@Overridepublic void show() {for (int i = 0; i < currentLength; i++) {System.out.print(elements[i] + "\t");}System.out.println();}
}

3. 调用测试

使用测试程序完成对该数据结构的测试,如下:

public class SequenceListTest {public static void main(String[] args) throws Exception {// 使用线性表对顺序表进行实现,初始化一个长度为5的空间IList list = new SequenceList(5);// 添加3个元素list.insert(0,10);list.insert(1,20);list.insert(2,30);// 查看第1个位置的元素System.out.println("第1个位置的元素为:" + list.get(0));// 查找值为20的数据元素System.out.println("元素20第一次出现的位置是" + list.indexOf(20));// 删除第三个位置的数据元素System.out.println("元素" + list.remove(2) + "已被成功删除");// 遍历顺序表list.show();// 查看当前数据元素个数System.out.println("当前数据元素个数为:" + list.length());// 清空顺序表list.clear();// 查看顺序表是否为空System.out.println(list.isEmpty() ? "顺序表为空" : "顺序表非空");}}

扫描下方二维码,加入官方粉丝微信群,可以与我直接交流,还有更多福利哦~

在这里插入图片描述

这篇关于一文学懂数据结构系列之:顺序表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083779

相关文章

JAVA利用顺序表实现“杨辉三角”的思路及代码示例

《JAVA利用顺序表实现“杨辉三角”的思路及代码示例》杨辉三角形是中国古代数学的杰出研究成果之一,是我国北宋数学家贾宪于1050年首先发现并使用的,:本文主要介绍JAVA利用顺序表实现杨辉三角的思... 目录一:“杨辉三角”题目链接二:题解代码:三:题解思路:总结一:“杨辉三角”题目链接题目链接:点击这里

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训