数据结构之线性表

基本概念

线性表,就是将数据排成像一条长线一样的结构,数组,链表,栈,队列都 是线性表结构,线性表上的数据最多只有前后两个方向,下面以一幅图的形式来展现一下线性表结构

在这里插入图片描述
补充:

与这种线性结构对应的就是非线性结构,比如后续要学习的数,堆,图等,在这些非线性数据结构 中,数据之间并不是简单的前后关系,如下图:

在这里插入图片描述

线性表的存储结构

线性表在计算机中可以用顺序存储和链式存储两种存储结构来表示:

  • 顺序存储结构的线性表:顺序表
  • 链式存储结构的线性表:链表又分为单链表、双向链表、循环链表

线性表的特点

  1. 由多个同类型发元素组成
  2. 因是线状的,除第一个和最后一个之外,最多只有两个方向
  3. 长度可以动态的增长或减少
  4. 可以访问所有元素
  5. 在任意位置进行插入和删除
  6. 求线性表的前驱和后继

线性表的基本操作

基本操作

1.线性表的置空操作:clear()
2.线性表判空操作:isEmpty()
3.求线性表元素的个数:length()、size()
4.求线性表的容量:getCapacity()
5.取元素操作:get(i)
6.插入操作:insert(i,x)
7.删除操作:remove(i)
8.查找操作:indexOf(i)
9.输出操作:display()

手写ArrayList

/**
 * 线性表的实现方式一:顺序表,采用数组实现
 * 换种说法:手写一个ArrayList(线性表的顺序结构的实现方式)
 *
 *  需要哪些内容?
 * 1 数组:存放数据
 * 2 size:存放数组中元素的个数
 *
 * 3 构造方法:空参构造,数组初始化大小10
 *            带参构造,数组大小就是传递过来的值
 * 4 getCapacity:获取数组容量,大小
 * 5 getSize:获取元素个数
 * 6 isEmpty:是否为空 ,size==0
 *
 *  Array<Student>
 *  Array<User>
 *  Array<Book>
 *
 */
public class Array<E> {

    //数组
    private E[] data;
    //元素的个数
    private int size;

    //空参构造
    public Array(){
        //调用本类的其他构造方法
        this(10);
    }

    //带参构造
    public Array(int capacity){
        data = (E[]) new Object[capacity];
        size = 0;
    }

    //获取数组容量
    public int getCapacity(){
        return data.length;
    }

    //获取元素个数
    public int getSize(){
        return size;
    }

    //判断是否为空 size==0
    public boolean isEmpty(){
        return size==0;
    }


    //向指定index索引新增元素e
    /**
     * 思路分析:
     * 1 防止数据被覆盖,所以需要从size-->index位置诺元素
     * 2 data[index] = e
     * 3 size++
     */
    public void add(int index,E e){
        //1 数组满?size == data.length
        if(size == data.length) {
//            throw new RuntimeException("数组已满,请扩容");
            resize(2 * data.length);
        }
        //2 index<0     index>size? index>data.length?
        //数组的长度为10,index = 10 ,size = 10
        // index=9 size=9
        // index = 0  size = 0
        if (index<0||index>size)
            throw new RuntimeException("索引非法");

        //1 挪:从sise-1的位置挪到index位置
        for (int i=size-1;i>=index;i--){
            data[i+1]=data[i];
        }
        //2 赋值
        data[index] = e;

        //3 size++
        size++;

    }


    //指定在队首新增
    public void addFirst(E e){
        add(0,e);
    }

    //指定在队尾新增
    public void addLast(E e){
        add(size,e);
    }

    //查找:list.get(i)
    public E get(int index){
        //索引非法判断
        if(index<0||index>=size)
            throw new RuntimeException("索引非法");

        //索引没问题
        return data[index];
    }


    //查找:list.find(e)
    //如果找到元素,返回索引index
    //如果找不到,返回-1
    //e全称element,元素
    public int find(E e){
        //1 遍历数组--if比较,找到返回index
        for (int i=0;i<size;i++){
            if (data[i].equals(e)){
                return i;
            }
        }

        //2 找不到,返回-1
        return -1;
    }

    //修改:修改指定index索引位置的元素
    public void set(int index,E e){
        if(index<0||index>=size)
            throw new RuntimeException("索引非法");
        data[index] = e;
    }


    //contains:包含:判断数组中是否包含某个元素
    //参数:判断的元素
    //返回值:true 存在,false不存在
    public boolean contains(E e){
        //遍历-比较
        for (int i=0;i<size;i++){
            if (data[i].equals(e)){
                return true;
            }
        }
        return false;
    }
    //设计remove的时候,需要返回刚刚被删除的值
    public E remove(int index){
        //1 判断index是否合法
        if (index<0||index>=size)
            throw new RuntimeException("索引非法");

        //2 保存要删除的值
        E del = data[index];

        //3 删除-移动元素-size位置清空,维护size
        for (int i = index+1;i<size;i++){
            data[i-1]=data[i];
        }

        data[size-1] = null;

        size--;

        //缩减容量
        if (size == data.length / 2)
            resize(data.length/2);


        //4 返回删除的值
        return del;
    }

    //删除首元素
    public E removeFirst(){
        return remove(0);
    }

    //删除最后一个元素
    public E removeLast(){
        return remove(size-1);
    }
    
    //删除指定元素
    public E removeElement(E e){
        int index = find(e);
        E remove = remove(index);
        return remove;
    }
    //动态扩容
    public void resize(int newCapacity){
        //1 创建一个新的数组
        E[] newData = (E[]) new Object[newCapacity];
        //2 将老数组的值一一复制过来
        for (int i=0;i<size;i++)
            newData[i] = data[i];
        //3 将新数组赋值给data
        data = newData;
    }



    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int i=0;i<data.length;i++){
            sb.append(data[i]);
            if(i!=data.length-1){
                sb.append(",");
            }
        }

        sb.append("]");

        return sb.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据老人家i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值