数据结构:图文详解顺序表的各种操作(新增元素,查找元素,删除元素,给指定位置元素赋值)

简介: 数据结构:图文详解顺序表的各种操作(新增元素,查找元素,删除元素,给指定位置元素赋值)

一.顺序表的概念

在线性数据结构中,我们一般分为俩类:顺序表和链表



       顺序表是一种线性数据结构,是数据元素按照线性顺序存储的数据结构,通常使用数组实现。顺序表中的元素以一定的顺序排列,每个元素都可以通过下标来进行访问。顺序表支持随机访问,可以快速地访问任意一个元素,但插入或删除元素时需要移动其余元素,效率较低。顺序表在内存中是一个连续的存储区域,数据元素紧密相邻存储,因此随机访问速度快。由于顺序表容量固定,当元素数量超过容量时需要重新分配内存空间,这可能会导致操作的耗时和内存使用的增加。


二.顺序表的实现

顺序表是一种数据结构,他和语言语法无关,语言只是通过不同的方式去描述这个数据结构,


举个通俗的例子说,假如湖面上有一座假山,而湖边有一群游客


有的人用英语说 “There is a rockery on the lake”


有的人用中文说 “湖面上有一坐假山”


有的人用日语说 “湖面に築山があります”


而这座假山就像是我们的数据结构,而我们使用的英语,中文,日语则是我们不同的编程语言。因此在学习数据结构的过程中,我们不必刻意去在意使用的什么语言什么语法,我们需要了解的是这个数据结构的本质和功能以及特性。笔者这里以Java作为顺序表的载体进行分享。


我们通常使用数值去实现顺序表,对于一个顺序表,它至少应该有以下俩个成员变量


  • 数组:用来存放数据和元素
  • 数组内存放的元素的个数:记录数组内元素的个数可以方便我们更好的进行增加删除等操作
public class MyArrayList{
    public int[] arr;//存放数据的数组
    public int usedSize;//记录数组内元素的个数
}


对于一个顺序表,它应该实现以下这些功能,我们将这些顺序表特有的功能和特性抽象出来一个接口,然后自己用代码去实现一个正真的顺序表。

public interface Ilist {
    // 新增元素,默认在数组最后新增
    public void add(int data);
    // 在 pos 位置新增元素
    public void add(int pos, int data);
    // 判定是否包含某个元素
    public boolean contains(int toFind);
    // 查找某个元素对应的位置
    public int indexOf(int toFind);
    // 获取 pos 位置的元素
    public int get(int pos);
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value);
    // 删除第一次出现的关键字key
    public void remove(int toRemove);
    // 获取顺序表长度
    public int size();
    // 清空顺序表
    public void clear();
}



新增元素

我们将新增元素分为俩种方式:默认尾部新增元素以及指定位置新增元素


默认尾部新增

在刚开始的时候,数组大小为我们设置的默认大小5,数组内部是没有元素的,也就是说默认的元素数量也是0,我们可以直接新增元素;但是数组的内容是有限的,当数组内容放满了后就需要扩容了,我们使用copyOf直接将原有数组的大小扩大一倍,再让这个数组重新接收扩容后的数组。


再来到具体的新增元素部分,usedSize相当于一直在记录顺序表最后一个元素,直接对当前顺序表最后一个位置放入数据data,并且记录元素的数量加一。

public static final int DEFAULT_SIZE = 5;
    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //判断满了之后要扩容
        if (arr.length == usedSize) {
            arr = Arrays.copyOf(arr, DEFAULT_SIZE * 2);
        }
        arr[usedSize] = data;
        usedSize++;
    }


指定位置添加元素

在添加之前先对要添加的位置进行判断,在顺序表中除了第一个节点之外每一个节点都有它的前驱,所以我们要确保添加的位置在序列中,如果不在序列中,我们就抛出一个自定义异常(这一步不是必须的)


在确定了输入的位置是合法的后,还要先判断顺序表是否已满,如果满了就进行扩容,在剩余空间充足的情况下就进行添加操作,在添加的时候需要进行元素的移动来为新的元素腾出位置,之后再在空出的位置上放入我们想要放入的元素,当我们完成新增后,记录元素个数的usedSize自然也要加一



代码实现:

    private void cheakPos(int pos) {
        if (pos < 0 || pos > usedSize)
            throw new ExceptionOfPos("pos位置不能为:" + pos);
    }    
    public void add(int pos, int data) {
        cheakPos(pos);
        //判断满了之后要扩容
        if (arr.length == usedSize) {
            arr = Arrays.copyOf(arr, DEFAULT_SIZE * 2);
        }
        //移动元素留出空位
        for (int i = usedSize - 1; i >= pos; i--) {
            arr[i + 1] = arr[i];
        }
        arr[pos] = arr[pos - 1];
        //给pos位置元素赋值
        arr[pos - 1] = data;
        usedSize++;
    }

 

public class ExceptionOfPos extends RuntimeException{
    public ExceptionOfPos(String message) {
        super(message);
    }
}


查找元素

查找可以按查找结果分为


  • 查找是否存在
  • 查找元素对应的位置
  • 查找指定位置对应的元素

查找是否存在

查找是相当最好实现的,因为我们并没有对顺序表进行内容上的改变,这也是顺序表最大的优势。查找只需要挨个遍历,看看是否有我们要找的元素,如果有就返回存在(true),如果没有就返回不存在(false)

    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (arr[i] == toFind)
                return true;
        }
        return false;
    }

 

查找元素对应的位置

挨个遍历,看看是否有我们要找的元素,如果有就返回元素的下标,如果没有就返回-1

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (arr[i] == toFind)
                return i + 1;
        }
        return -1;
    }


查找指定位置对应的元素

在判定输入位置和顺序表的合法性后(不一定非要抛出异常,笔者这里只是给个思路),直接返回目标位置的元素就可以了

    // 获取 pos 位置的元素
    public int get(int pos) {
        //检查输入位置是否合法
        cheakPos(pos);
        //检查顺序表是否为空
        cheakEmpty();
        return arr[pos];
    }
    private void cheakPos(int pos) {
        if (pos < 0 || pos > usedSize)
            throw new ExceptionOfPos("pos位置不能为:" + pos);
    }
    private void cheakEmpty() {
        if (usedSize == 0)
            throw new ExceptionOfEmpty("当前顺序表为空,无法操作");
    }

 

删除元素

删除之前得先判断顺序表是否为空,在不为空的情况下,我们利用刚才写的查找方法indexOf找到要删除的元素的位置,然后将元素从后往前依次覆盖就可以了,因为最后一个元素的后面是没有元素的,所以我们要进行手动覆盖,元素减少之后,对应的记录数量的usedSize也得减一


    //删除第一次出现的关键字key
    public void remove(int toRemove) {
        //检查顺序表是否为空
        cheakEmpty();
        int delPos = indexOf(toRemove);
        for (int i = delPos; i < usedSize; i++) {
            arr[i-1] = arr[i];
        }
        arr[usedSize-1] = arr[usedSize];
        usedSize--;
    }

 

获取顺序表长度

因为usedSize保存了顺序表元素的个数,也就是顺序表的长度,所以在判断顺序表非空后直接返回usedSize就可以

    // 获取顺序表长度
    public int size() {
        //检查顺序表是否为空
        cheakEmpty();
        return usedSize;
    }

 

清空顺序表

直接将元素的个数置为0,其余的方法就无法通过usedSize去操作顺序表了,也就完成了顺序表的清空

    // 清空顺序表
    public void clear() {
        usedSize = 0;
    }


 本次的分享就到此为止了,希望我的分享能给您带来帮助,也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见


目录
相关文章
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
582 5
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
717 3
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
525 4
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
299 6
|
存储 Java 程序员
【数据结构】初识集合&深入剖析顺序表(Arraylist)
Java集合框架主要由接口、实现类及迭代器组成,包括Collection和Map两大类。Collection涵盖List(有序、可重复)、Set(无序、不可重复),Map则由键值对构成。集合通过接口定义基本操作,具体实现由各类如ArrayList、HashSet等提供。迭代器允许遍历集合而不暴露其实现细节。List系列集合元素有序且可重复,Set系列元素无序且不可重复。集合遍历可通过迭代器、增强for循环、普通for循环及Lambda表达式实现,各有适用场景。其中ArrayList实现了动态数组功能,可根据需求自动调整大小。
297 11
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
354 3