数据结构2:线性表介绍与顺序表

概念

线性结构是最常见的一种数据结构,其特点是数据元素之间存在一对一线性关系。
线性结构实现有两种存储结构:顺序存储结构(数组)和链式存储结构(链表)。顺序存储的线性表称为顺序表。
线性结构常见有:顺序表、队列、链表、栈。

  • 关于数组、顺序表、链表等概念
    • 线性表:属于逻辑结构中的线性结构,它包括顺序表和链表。
    • 顺序表:用顺序存储(数组)实现的线性表。
    • 链表:用链式存储实现的线性表。
    • 数组:一种物理结构,它的存储单元是连续的。

顺序表

顺序表是以数组形式保存的线性表,逻辑结构上相邻的元素物理存储结构上也相邻。

import java.util.Iterator;

public class MySequenceList<T> implements Iterable<T> {
    //存储元素的数组
    private T[] eles;
    //当前顺序表元素个数
    private int N;


    public MySequenceList(int capacity){
        if(capacity >= 1){
            this.eles = (T[]) new Object[capacity];
            this.N = 0;
        }else {
            this.eles = (T[]) new Object[1];
            this.N = 0;
        }
    }

    public MySequenceList(){
        //默认大小为10
        this.eles = (T[]) new Object[10];
        this.N = 0;
    }

    //清空线性表
    public void clear(){
        this.N = 0;
    }

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

    //返回顺序表长度
    public int length(){
        return N;
    }

    //获取第i个元素
    public T get(int i){
        if(i <= N){
            return eles[i];
        }
        return null;
    }

    //末尾插入
    public void insert(T t){
        //判断数组是不是满了,满了就扩容
        if(N >= eles.length)
            resize(2 * eles.length);
        eles[N++] = t;
    }
    //指定位置插入
    public void insert(int i,T t){
        //判断i是否落在有数据的地方
        if(0 <= i && i <= N){
            //判断数组是不是满了,满了就扩容
            if(N >= eles.length)
                resize(2 * eles.length);
            for(int index = N;index > i;index--){
                eles[index] = eles[index - 1];
            }
            eles[i] = t;
            N++;
        }

    }

    //删除
    public T remove(int i){
        //判断i是否落在有数据的地方
        if (i >= 0 && i < N) {
            T current = eles[i];
            for(int index = i;index<N-1;index++){
                eles[index] = eles[index+1];
            }

            N--;
            //如果用到的地方太少就缩容
            if(N < eles.length / 4){
                resize(eles.length/2);
            }
            return current;
        }
        return null;
    }

    //重新设定数组大小
    public void resize(int newSize){
        T[] temp = eles;
        eles = (T[]) new Object[newSize];

        for (int i = 0;i < N;i++){
            eles[i] = temp[i];
        }
    }

    //获取元素下标
    public int indexOf(T t){
        for(int i = 0;i <N;i++){
            if(eles[i].equals(t)){
                return i;
            }
        }
        return -1;
    }


    //提供遍历方法
    @Override
    public Iterator<T> iterator(){
        return new SIterator();
    }
    //自定义内部类用于遍历
    private class SIterator implements Iterator{

        private int cusor;

        public SIterator(){
            this.cusor = 0;
        }
        @Override
        public boolean hasNext(){
            return cusor < N ;
        }
        @Override
        public Object next(){
            return eles[cusor++];
        }
    }

    public static void main(String[] args) {
        MySequenceList<String> test = new MySequenceList<>();
        test.insert("111");
        test.insert("222");
        test.insert("333");
        test.insert(1,"bbb");
        test.remove(2);
        test.insert(3,"444");
        test.insert(-1,"ccc");
        test.insert(5,"ddd");
        for(String s : test){
            System.out.println(s);
        }
        System.out.println(test.length());
        System.out.println(test.indexOf("bbb"));
        System.out.println(test.indexOf("222"));

        System.out.println("============");

        MySequenceList<String> test2 = new MySequenceList<>(-2);
        test2.insert("111");
        test2.insert("222");
        for(String s : test2){
            System.out.println(s);
        }
    }
}

顺序表操作的时间复杂度

假如数组的长度为 n。
访问:O(1)//访问特定位置的元素
插入:O(n )//最坏的情况发生在插入发生在数组的首部并需要移动所有元素时
删除:O(n)//最坏的情况发生在删除数组的开头发生并需要移动第一元素后面所有的元素时
顺序表底层是由数组实现的,涉及到扩容操作,这样导致顺序表在使用过程中时间复杂度不是线性的,在需要扩容的节点处,耗时会

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值