0
点赞
收藏
分享

微信扫一扫

【用数组实现线性表(可以随意添加数据的数组)】

少_游 2022-01-28 阅读 32

用数组实现线性表(可以随意添加数据的数组)

为什么需要线性表?

  • 数组:按照索引操作都快
    • 下标查找快
    • 插入慢
    • 不能扩容: 连续的一块内存空间(所以不能随意修改数据)
    • 下标不方便管理
    • 比较查找慢
  • 链表:
    • 查找慢
    • 可以扩容: 不需要连续
    • 插入快

线性表接口设计:

  • 抽象方法:
  • 基本信息提供: 现有元素个数
  • 增删查改:
  • 排序输出:(这里没有实现,大概思路是用hashCode实现,之后会专门写一篇排序)
  • 合并: 数组合并数组 数组合并链表 链表合并数组 链表合并链表(这里只实现了数组的部分,链表的之后会专门写一篇)

设计数组实现的线性表:

  • 存储结构: Object类型数组

  • 元素个数/下标

  • 长度/容量

  • 默认长度/默认容量

  • 初始化不同的构造方法:

    • 构造方法:
      • 根据 传入的容量初始化
      • 根据一个现有数组/链表/同类型线性表初始化
      • 默认的初始化方法
    • add: 考虑扩容算法
      • 单个元素
      • 数据结构 数组
    • get:
      • 根据下标获取元素
      • 根据元素获取多个下标
      • 根据集合(数组、链表)获取 数组
    • remove: 移位
      • 根据下标获取元素,然后移位
      • 根据元素获取多个下标,然后移位
      • 根据集合获取,然后移位
    • sort: 排序(这里没有实现,下次专门写一篇)

具体的代码

线性表(MyArrylist)类的一些参数

使用泛型是方便存取各类数据


public class MyArrayList <E> implements MyList {
    private Object[] valueArray = {};
    private int length;   //容量   容量=下标+1
    private int size;     //下标
    private static final int defaultLength = 10;

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

    public int getLength() {
        return length;
    }

初始化构造函数

public MyArrayList(int inlength) {
        if ((int)inlength <= 0) {
            System.err.println("输入容量越界!!"+inlength);
        }
        if ((int)inlength <= 10) {
            length = defaultLength;
            valueArray = new Object[length];
        }
        if ((int)inlength > 10 && (int)inlength < Integer.MAX_VALUE - 100) {
            length = (int)inlength;
            valueArray = new Object[length];
        }
        if ((int)inlength >= Integer.MAX_VALUE - 100) {
            System.err.println("推荐使用大线性表!!");
        }
        size = 0;
    }//根据传入的容量初始化构造

public MyArrayList() {

        length = defaultLength;//10
        valueArray = new Object[length];
        size = 0;
    }//默认初始化大小是10

根据数组构造

public MyArrayList(E[] objects) {

        int length = objects.length;
        int size   =0;

        Object[] newArry = new Object[length];

        for (int i = 0; i < length; i++) {

            newArry[i] = objects[i];
            if (objects[i] !=null){
                size++;
            }
        }
        this.length = length;
        this.valueArray = newArry;
        this.size =size;

    }//根据数组构造

根据单个元素扩容

public void add(E e) {

        //size =size+1;   //方法2 没有这句话
        if (size >= length) {
            // 扩容
            // 换一个大一点的数组
            int oldLength = length;
            int newLength = oldLength + (oldLength >> 1); //乘以1.5,2进制退位
            length = newLength;
            Object[] newArray = new Object[length];

            for (int i = 0; i < oldLength; i++) {
                newArray[i] = valueArray[i];
            }
            //替换引用
            valueArray = newArray;
            newArray = null;
        }
        valueArray[size++] = e; //方法2 valueArry[Size++] =e
    } //根据单个元素扩容

根据数组添加

public void add(E[] objects) {

        int length_new = objects.length + this.length;

        Object[] newArry = new Object[length_new];

        for (int i = 0; i < this.length; i++) {

            newArry[i] = valueArray[i];
        }//添加原本的数组

        for (int i = this.length; i < length_new; i++) {

            newArry[i] = objects[(i-this.length)];

            System.out.println("原来的"+i);
            System.out.println("现在的"+(i-this.length));
        }//添加新的的数组


        this.length = length_new;
        this.valueArray = newArry;
        this.size = size+objects.length;

    }//根据数组添加

根据下标获取元素

 /**
     * 根据下标遍历
     * @param index 传入的下标
     * @return 返回目标下标的元素
     */
    public Object get(int index) {
        System.out.println("获取下标为"+index);
        if(index<size&&index>=0){
            return  valueArray[index];
        }
        System.err.println("数组里面没有这个对象");
        return  null;

    } //根据下标获取元素

根据元素获取多个下标

public MyArrayList<Integer> get(E object) {
        int num_add = 0;
        MyArrayList<Integer> indexArr = new MyArrayList<Integer>();
        for (int i = 0; i < size; i++) {
            if (valueArray[i].equals(object)) {
                num_add++;
                indexArr.add(i);
                System.out.println("numadd++");
                //((Integer)valueArray[i]).equals(anoint)
            }
        }
        System.out.println("重复的个数 "+num_add);
        if(num_add==0){
            return null;
        }
        return indexArr;
        
    } //根据元素获取多个下标

根据数组,获取数组第一个元素位置

 /**
     * 这里把【1,2】看成一个整体,返回的是数组第一个元素的位置
     * @param objects
     * @return Interger
     */

    public Integer get(E[] objects){

        for (int i = 0; i < objects.length; i++) {
        //查找对象
            for (int j = 0; j < valueArray.length; j++) {
            //原来数组
                System.out.println("查找对象"+i);
                System.out.println("原来数组"+j);

                if (valueArray[j] .equals(objects[i]) ) {

                    if (i == (objects.length - 1)) {
                    // 循环到查找对象的最后一位了      这里的i是查找对象的最后一个,j是原来数组对应的查找对象的最后一个元素
                        i=0;//为返回数组做准备,这里用不到
                     return (j+1- objects.length); //减去长度,是第一个元素的位子
                    }//找到了查找对象的位子
                    i =i+1;
                }else {
                    i=0;
                }
            }
        }
        System.out.println("没有这些元素");
        return null;
    }//根据数组返回位置

移位函数:删除所有的Null,节省空间

public void removeNull(){
        int removeNumber=0;
        for (int i=0; i< valueArray.length;i++){
            if(valueArray[i] ==null){
                removeNumber++;
            }
        }
        Object []newarry =new Object[valueArray.length-removeNumber];
        for (int i=0; i< valueArray.length;i++){

            int j=0;
            if(valueArray[i] !=null){

                newarry[i-j]= valueArray[i];
            }
            else {
                j++;
            }
        }
        valueArray =newarry;
        length =length -removeNumber;
    }

根据下标获取单个元素,然后移位

    public void remove(int object){

        Object[] newArry = new Object[length-1];

       for (int i=0; i<object;i++){

           newArry[i] = valueArray[i];
       }

       for (int i=(object+1); i<length; i++){

           newArry[i-1] = valueArray[i];
       }
       valueArray = newArry;
       length=length-1;
       size=size-1;
       newArry=null;
       System.out.println ("文件已经删除");
        this.removeNull();

    }//根据下标获取元素,然后移位

根据单个元素获取多个下标,然后移位

 public void remove(E object) {

        int number = 0;
        for (int i = 0; i < size; i++) {

            if(valueArray[i]!=null){
                if (valueArray[i].equals(object)  ) {

                    number++;
                }
            }
        }
        Object[] newarry = new Object[length - number];

        int cut_number = 0;
        for (int i = 0; i < length; i++) {

            if(valueArray[i]!=null){

                if (valueArray[i].equals(object) ) {
                    cut_number++;

                } else {
                    newarry[i - cut_number] = valueArray[i];
                }
            }

        }

        valueArray = newarry;
        length =length - number;
        size =size - number;

    }//根据单个元素获取多个下标,然后移位

根据数组获取多个元素的多个下标,然后移位


/**
     * 这里删除传入数组中的所有元素,包括重复的
     * 最后没有改length是因为 removeNull 会改length
     * @param objects
     */
    public void remove(E[] objects) {


        int removeNumber =0;

        for (int i = 0; i < objects.length; i++) {
            //传入数组
            for (int j = 0; j < valueArray.length; j++) {
                //原来的数组
                    if(objects[i].equals(valueArray[j])){

                        objects[i] =null;
                        removeNumber++;
                    }
            }
        }

        size =size-removeNumber;

        this.removeNull();
    }

拖了2天终于写完了,下一一定不要拖!!。

举报

相关推荐

0 条评论