【数据结构】顺序表的原理及实现

简介: 【数据结构】顺序表的原理及实现

1.什么是顺序表

  • 顺序表是用一段物理地址连续的存储单元进行存储元素的线性结构,通常是以数组进行存储。
  • 通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。

c4ce1e798af24d3485c56b1be43957ce.jpg

2.顺序表的实现

判断顺序表是否为空表 public boolean isEmpty()
判断顺序表是否满 public boolean ifFull()
向顺序表中添加元素 public void add(T ele)
删除指定位置的元素 public void delete(int index)
删除指定的元素 public void remove(T ele)
在指定的位置添加元素 public void add(int index,T ele)
修改数据 public void update(int index,T ele)
获取顺序表的长度 public int size()
获取对应位置的元素 public T getIndex(int index)
遍历输出顺序表 public void show()


a38fb7584cb54c658d8c068668fde394.jpg

(1)顺序表定义


40d5716a8c624823ad89c5391df3d4da.jpg

(2)判断集合是否为满


16cc2efc444248b7959c0463af88cd8d.jpg

(3)判断集合是否为空


e45e5852c5344365bfe0c5bb8bb9e834.jpg

(4)遍历顺序表元素

6b7359c729cf423c96da3f1d8f5e3dd3.jpg

(5)向顺序表中添加元素c985b26b86b746389fa5eebc7103e1d3.jpg


(6)获取元素的下标索引

cd636c5cb90f44a89e0f26075a1b1476.jpg

(7)向顺序表中删除指定元素

2cfeea8daae340cb992eb4c75ae696c0.jpg

(8)修改指定下标元素

0cf465f45aa3471285a954cd17780ef8.jpg

(9)获取有效元素个数

16496e4934ff4b0bb95014ea1a9db25f.jpg

(10)顺序表扩容


1c44583998254bf49b21cbafe7aee8c6.jpg

# 修改add方法中判断元素是否已经满了的逻辑
# 如果元素已经满了,则进行扩容原长度的2倍
# 同时修改容量的大小
if(isFull()){
    this.size = list.length*2;
    reList(this.size);
}

(11)获取顺序表的最大容量

0bc3b08bd93746e5bdcb15d164293f2d.jpg

3.顺序表功能验证

(1)整体顺序表实现代码

/**
 * @description 顺序表数据结构实现
 * @author lixiang
 * @param <T>
 */
public class SequenceList<T> {
    /**
     * 定义默认的数组长度
     */
    private final static int DEFAULT_SIZE = 10;
    /**
     * 定义存储数组
     */
    private T[] list;
    /**
     * 定义顺序表的有效元素个数
     */
    private int num;
    /**
     * 定义数组的长度
     */
    private int size;
    /**
     * 无参构造方法,默认长度10
     */
    public SequenceList(){
        list = (T[]) new Object[DEFAULT_SIZE];
        this.size = DEFAULT_SIZE;
        this.num=0;
    }
    /**
     * 有参构造,长度为size
     * @param size
     */
    public SequenceList(int size){
        list = (T[]) new Object[size];
        this.size = size;
        this.num=0;
    }
    /**
     * 顺序表的判空实现
     * @return
     */
    public boolean isEmpty(){
        return num==0;
    }
    /**
     * 顺序表的判满实现
     * @return
     */
    public boolean isFull(){
        return num==list.length;
    }
    /**
     * 顺序表的遍历
     */
    public void showNum(){
        for(int i=0;i<num;i++){
            System.out.println(list[i]);
        }
    }
    /**
     * 顺序表添加元素,添加到指定的下标下
     * @param index
     * @param ele
     */
    public void add(int index,T ele){
        if(isFull()){
            //这块后续会加上扩容的方法
            this.size = list.length*2;
            reList(this.size);
        }
        //如果index 为 -1 表示直接插入末尾
        if(index == -1){
            list[num++]=ele;
            return;
        }
        //不为-1的话,则插入到指定的下标
        if(index<0 || index>num){
            System.out.println("参数不合法");
        }
        //把i的位置腾出来 i位置的元素全部向后移动一位
        if (num - index >= 0) System.arraycopy(list, index, list, index + 1, num - index);
        //直接插入元素
        list[index]=ele;
        num++;
    }
    /**
     * 顺序表添加元素,添加到末尾
     * @param ele
     */
    public void add(T ele){
        this.add(-1,ele);
    }
    /**
     * 删除指定位置的元素
     * @param ele
     */
    public void delete(int index){
        if(index <0 || index>num){
            System.out.println("参数不合法");
        }
        //把每个元素向前移动一位
        if (num - (index + 1) >= 0) System.arraycopy(list, index + 1, list, index + 1 - 1, num - (index + 1));
        num--;
    }
    /**
     * 删除指定元素
     * @param ele
     */
    public void remove(T ele){
        //获取元素下标索引
        int index = this.indexOf(ele);
        if(index == -1){
            System.out.println("当前元素不存在:"+ele);
        }
        //删除元素
        this.delete(index);
    }
    /**
     * 获取元素的下标索引
     * @param ele
     * @return
     */
    public int indexOf(T ele){
        for (int i = 0; i < list.length; i++) {
            if(list[i].equals(ele)){
                return i;
            }
        }
        return -1;
    }
    /**
     * 修改指定下标元素
     * @param index
     * @param ele
     */
    public void update(int index,T ele){
        list[index]=ele;
    }
    /**
     * 获取元素个数
     * @return
     */
    public int getNum(){
        return num;
    }
    /**
     * 扩充顺序表容量
     * 私有方法,不对外提供,在插入元素时,判断是否已经满的情况下调用
     * 如果顺序表的元素已经满了,则调用扩容方法
     * @param size
     */
    private void reList(int size){
        //保存之前的顺序表
        T []temp=list;
        //创建新的顺序表
        list = (T[]) new Object[size];
        //拷贝元素
        System.arraycopy(temp, 0, list, 0, temp.length);
    }
    /**
     * 返回顺序表容量大小
     * @return
     */
    public int size(){
        return size;
    }
}

(2)验证顺序表初始化

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>();
        SequenceList<Integer> sequenceCustomSizeList = new SequenceList<>(5);
        System.out.println("默认定义顺序表容量大小:"+sequenceDefaultSizeList.size());
        System.out.println("自定义顺序表容量大小:"+sequenceCustomSizeList.size());
    }
}

0786f7c3f4f74dafaf8f83b3d5eb4fd0.jpg(2)验证添加元素

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>();
        //添加1 2 3 元素
        sequenceDefaultSizeList.add(1);
        sequenceDefaultSizeList.add(2);
        sequenceDefaultSizeList.add(3);
        //输出
        sequenceDefaultSizeList.show();
    }
}

b725f805c20c4079828ef8e720282896.jpg

(3)验证修改元素

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>();
        //添加1 2 3 元素
        sequenceDefaultSizeList.add(1);
        sequenceDefaultSizeList.add(2);
        sequenceDefaultSizeList.add(3);
        //输出
        sequenceDefaultSizeList.show();
        sequenceDefaultSizeList.update(0,9);
        sequenceDefaultSizeList.show();
    }
}

f55378d049cd46ce9cde9e2719b0f4d8.jpg

(4)验证删除元素

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>();
        //添加1 2 3 元素
        sequenceDefaultSizeList.add(1);
        sequenceDefaultSizeList.add(2);
        sequenceDefaultSizeList.add(3);
        //输出
        sequenceDefaultSizeList.show();
        sequenceDefaultSizeList.delete(0);
        sequenceDefaultSizeList.show();
    }
}

db37b1a779054bb2807f557030a006d2.jpg

(5)验证集合扩容

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>(2);
        System.out.println("扩容前:"+sequenceDefaultSizeList.size());
        //添加1 2 3 元素
        sequenceDefaultSizeList.add(1);
        sequenceDefaultSizeList.add(2);
        sequenceDefaultSizeList.add(3);
        //输出
        System.out.println("扩容后:"+sequenceDefaultSizeList.size());
    }
}

12c018589bde452ca8918e989576f2c3.jpg

(6)验证获取元素的下标索引

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>(2);//添加1 2 3 元素
        sequenceDefaultSizeList.add(1);
        sequenceDefaultSizeList.add(2);
        //输出
        System.out.println("元素index:"+sequenceDefaultSizeList.indexOf(2));
    }
}

91a8a6d473d94bb08c750b39060c77a4.jpg

(7)获取当前集合有效元素个数

public class Main {
    public static void main(String[] args) {
        SequenceList<Integer> sequenceDefaultSizeList = new SequenceList<>(4);//添加1 2 3 元素
        sequenceDefaultSizeList.add(1);
        sequenceDefaultSizeList.add(2);
        //输出
        System.out.println("当前集合有效元素个数为:"+sequenceDefaultSizeList.getNum());
    }
}


21a5927a208c4814a74bc7ca5860d5b1.jpg

4.顺序表的优缺点

  • 优点:
  • 按照索引查询元素速度快
  • 按照索引遍历数组方便
  • 可以随机访问其中的元素
  • 缺点:
  • 根据内容查找元素速度慢,需遍历全部集合
  • 数组的大小一经确定不能改变,不适合动态存储,手动扩容
  • 增加、删除元素效率慢


相关文章
|
1月前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
51 2
|
19天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
19天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
50 3
|
19天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
30 6
|
1月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
23 3
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
19 2
|
1月前
|
消息中间件 存储 Java
数据结构之 - 深入探析队列数据结构: 助你理解其原理与应用
数据结构之 - 深入探析队列数据结构: 助你理解其原理与应用
30 4
|
1月前
|
存储 算法 索引
【数据结构】——顺序表
【数据结构】——顺序表
|
1月前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
22 1