数据结构-java-模拟实现顺序表(数组&链表实现)

本文介绍了如何使用Java实现顺序存储的ArrayList和链式存储的LinkedList,讨论了它们在插入、删除和获取元素方面的特点,以及两者之间的区别。重点在于线性表的基本概念和两种常见实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当前遇到一个问题

我们希望能够将数据按顺序存放,支持在某个位置插入一条数据、删除一条数据、修改一条数据等,如果使用数组的话这时候,就显得有些乏力了,因为数组的长度是固定。

我们实现一个新的数据结构:线性表

线性表是由同一类型的数据元素构成的有序序列的线性结构。线性表中元素的个数就是线性表的长度,表的起始位置称为表头,表的结束位置称为表尾,当一个线性表中没有元素时,称为空表。

线性表一般需要包含以下功能:

初始化线性表:将一个线性表进行初始化,得到一个全新的线性表。
获取指定位置上的元素:直接获取线性表指定位置i上的元素。
获取元素的位置:获取某个元素在线性表上的位置i。
插入元素:在指定位置i上插入一个元素。
删除元素:删除指定位置i上的一个元素。
获取长度:返回线性表的长度。

实现线性表的结构一般有两种,一种是顺序存储实现,还有一种是链式存储实现,我们先来看第一种,也是最简单的的一种。

public class ArrayList<E> {
    private int size=0 ;// 当前顺序表的大小
    private int capacity=10;//数组的容量
    private Object[] array = new Object[capacity];

    // 新增一个元素
    public void add(E element,int index){
        if(index<0 || index > size){
            throw new IndexOutOfBoundsException("插入位置非法,合法插入的位置为:0 ~ "+size);
        }

        if(size >= capacity){
            int newCapacity = capacity + (capacity >> 1); //扩容为原来的1.5倍
            Object[] newArray = new Object[newCapacity];
            System.arraycopy(array,0,newArray,0,size);
            array = newArray;
            capacity = newCapacity;
        }

        for (int i = size; i > index; i--) {
            array[i] = array[i-1];
         }

        array[index] = element;
        size++;
    }


    // 删除一个元素
    public E remove(int index){
        if (index<0|| index> size-1){
            throw new IndexOutOfBoundsException("删除位置非法,合法删除的位置为:0 ~ "+(size-1));
        }
        for (int i = index; i < size; i++) {
            array[i] = array[i+1];
        }
        size--;
        return (E) array[index];
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i <  size; i++) {
            stringBuilder.append(array[i]).append(" ");
        }

        return stringBuilder.toString();
    }
}

我们接着来看第二种方式,我们可以使用链表来实现,那么什么是链表呢?

链表不同于顺序表,顺序表底层采用数组作为存储容器,需要分配一块连续且完整的内存空间进行使用,而链表则不需要,它通过一个指针来连接各个分散的结点,形成了一个链状的结构,每个结点存放一个元素,以及一个指向下一个结点的指针,通过这样一个一个相连,最后形成了链表。它不需要申请连续的空间,只需要按照顺序连接即可,虽然物理上可能不相邻,但是在逻辑上依然是每个元素相邻存放的,这样的结构叫做链表(单链表)
 

public class LinkList<E> {
    class ListNode {
        public E val;
        public ListNode next;

        public ListNode(E val) {
            this.val = val;
        }
    }

    public ListNode head;

    //遍历单链表
    public void show() {
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

    // 头插法
    public void addFirst(E data){
        ListNode node = new ListNode(data);
        node.next = head;
        head = node;
    }

    // 尾插法
    public void  addLast(E data){
        ListNode node = new ListNode(data);

        if (head==null){
            head = node;
            return;
        }

        ListNode cur = head;
        while (cur.next!=null){ //需要提前判断 cur.next是否存在
            cur = cur.next;
        }

        cur.next = node;
    }

    public int size(){
        int size=0;

        ListNode cur = head;
        while (cur!=null){
            cur = cur.next;
            size++;
        }

        return size;
    }

    // 随意位置插入
    public void  add(E data,int index){
        // index合法位置判断
        int len = size();

        if(index <0 || index > len){
            return;
        }

        if (index == 0) {
            addFirst(data);
            return;
        }
        if (index == size()) {
            addLast(data);
            return;
        }

        ListNode cur = getIndexData(index);
        ListNode node = new ListNode(data);

        node.next = cur.next;
        cur.next = node;
    }


    public ListNode getIndexData(int index){
        ListNode cur = head;
        while (index!=0){
            cur = cur.next;
            index--;
        }
        return cur;
    }

    public void remove(int index){
        if(index <0 || index > size()){
            return;
        }
        if(index==0){
            head.next=null;
        }
        ListNode indexData = getIndexData(index - 1);
        indexData.next = indexData.next.next;
    }
}

ArrayList和LinkedList的区别

参考 数据结构与算法(一)线性结构篇_线性层的a与b_青空の霞光的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值