当前位置:   article > 正文

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

顺序表添加元素


 目录

一.顺序表的概念

二.顺序表的实现

新增元素

默认尾部新增

指定位置添加元素

查找元素

查找是否存在

查找元素对应的位置

查找指定位置对应的元素

删除元素

获取顺序表长度

清空顺序表


一.顺序表的概念

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

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

二.顺序表的实现

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

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

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

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

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

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

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

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

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

  1. public interface Ilist {
  2. // 新增元素,默认在数组最后新增
  3. public void add(int data);
  4. // 在 pos 位置新增元素
  5. public void add(int pos, int data);
  6. // 判定是否包含某个元素
  7. public boolean contains(int toFind);
  8. // 查找某个元素对应的位置
  9. public int indexOf(int toFind);
  10. // 获取 pos 位置的元素
  11. public int get(int pos);
  12. // 给 pos 位置的元素设为 value
  13. public void set(int pos, int value);
  14. // 删除第一次出现的关键字key
  15. public void remove(int toRemove);
  16. // 获取顺序表长度
  17. public int size();
  18. // 清空顺序表
  19. public void clear();
  20. }

新增元素

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

默认尾部新增

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

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

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

指定位置添加元素

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

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

代码实现:

  1. private void cheakPos(int pos) {
  2. if (pos < 0 || pos > usedSize)
  3. throw new ExceptionOfPos("pos位置不能为:" + pos);
  4. }
  5. public void add(int pos, int data) {
  6. cheakPos(pos);
  7. //判断满了之后要扩容
  8. if (arr.length == usedSize) {
  9. arr = Arrays.copyOf(arr, DEFAULT_SIZE * 2);
  10. }
  11. //移动元素留出空位
  12. for (int i = usedSize - 1; i >= pos; i--) {
  13. arr[i + 1] = arr[i];
  14. }
  15. arr[pos] = arr[pos - 1];
  16. //给pos位置元素赋值
  17. arr[pos - 1] = data;
  18. usedSize++;
  19. }
  1. public class ExceptionOfPos extends RuntimeException{
  2. public ExceptionOfPos(String message) {
  3. super(message);
  4. }
  5. }

查找元素

查找可以按查找结果分为

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

查找是否存在

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

  1. // 判定是否包含某个元素
  2. public boolean contains(int toFind) {
  3. for (int i = 0; i < usedSize; i++) {
  4. if (arr[i] == toFind)
  5. return true;
  6. }
  7. return false;
  8. }

查找元素对应的位置

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

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

查找指定位置对应的元素

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

  1. // 获取 pos 位置的元素
  2. public int get(int pos) {
  3. //检查输入位置是否合法
  4. cheakPos(pos);
  5. //检查顺序表是否为空
  6. cheakEmpty();
  7. return arr[pos];
  8. }
  9. private void cheakPos(int pos) {
  10. if (pos < 0 || pos > usedSize)
  11. throw new ExceptionOfPos("pos位置不能为:" + pos);
  12. }
  13. private void cheakEmpty() {
  14. if (usedSize == 0)
  15. throw new ExceptionOfEmpty("当前顺序表为空,无法操作");
  16. }

删除元素

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

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

获取顺序表长度

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

  1. // 获取顺序表长度
  2. public int size() {
  3. //检查顺序表是否为空
  4. cheakEmpty();
  5. return usedSize;
  6. }

清空顺序表

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

  1. // 清空顺序表
  2. public void clear() {
  3. usedSize = 0;
  4. }



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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/922170
推荐阅读
相关标签
  

闽ICP备14008679号