顺序表 之 Java

ArrayList 与顺序表

顺序表

顺序表是用一段 物理地址连续的存储单元依次存储的线性结构 , 一般情况下采用数组存储 . 在数组上完成数据的增删查改

假设有一组数据:

public int[] elem;
public int usedSize;//存储了多少个有效的数据
public static final int DEFAULT_SIZE = 5;

public MyArrayList() {
    this.elem = new int[DEFAULT_SIZE];
}

打印顺序表

public void display() {
    for (int i = 0; i < this.usedSize; i++) {
        System.out.print(this.elem[i] + " ");
    }
    System.out.println(" ");

}

新增元素

默认在数组最后新增

  1. 先检查数组是否为满

    public boolean isFull() {
        /*if(this.usedSize == this.elem.length) {
            return  true;
        }
        return false;*/
        return this.usedSize == this.elem.length;
    }
    
  2. 如果数组满了 , 进行数组扩容

    private void resize() {
        this.elem = Arrays.copyOf(this.elem,2*this.elem.length);//扩容
    }
    
// 新增元素,默认在数组最后新增
public void add(int data) {
    if(this.isFull()) {
        resize();
    }
    this.elem[this.usedSize] = data;
    this.usedSize++;
}

在pos 位置新增元素

  1. 先检查pos 位置的合法性

    private void checkIndex(int pos) {
        if (pos < 0 || pos > usedSize) {
            throw new IndexOutOfException("位置不合法,请检查位置的合法性");
        }
    }
    
  2. 再判断数组是否为满

    //判断是否为满
    public boolean isFull() {
        /*if(this.usedSize == this.elem.length) {
            return  true;
        }
        return false;*/
        return this.usedSize == this.elem.length;
    }
    
  3. 如果数组满了 , 进行扩容

    private void resize() {
        this.elem = Arrays.copyOf(this.elem,2*this.elem.length);//扩容
    }
    
public void add(int pos, int data) {

    checkIndex(pos);//检查pos的合法性

    if (isFull()) {
        resize();
    }
    for (int i = usedSize - 1; i >= pos; i--) {
        elem[i+1] = elem[i];
    }
    elem[pos] = data;
    usedSize++;

}

判断是否包含某个元素

public boolean contains(int toFind) {
    for (int i = 0; i < this.usedSize; i++) {
        if(this.elem[i] == toFind) {
            return true;
        }
    }
    return false;
}

查找某个元素对应的位置

// 查找某个元素对应的位置
public int indexOf(int toFind) {
    for (int i = 0; i < this.usedSize; i++) {
        if(this.elem[i] == toFind) {
            return i;
        }
    }
    return -1; //因为数组没有负数下标
}

获取 pos 位置的元素

public int get(int pos) {
    checkGetIndex(pos);
    return elem[pos];
}
private void checkGetIndex(int pos) {
    if (pos < 0 || pos >= usedSize) {
        throw new IndexOutOfException("get元素的时候,位置不合法,请检查位置的合法性");
    }
}

抛异常

public class IndexOutOfException extends RuntimeException{
    public IndexOutOfException() {

    }
    public IndexOutOfException(String msg) {
        super(msg);
    }
}

给pos位置元素设为 value

  1. 检查 pos 位置是否合法

    private void checkIndex(int pos) {
        if (pos < 0 || pos > usedSize) {
            throw new IndexOutOfException("位置不合法,请检查位置的合法性");
        }
    }
    
public void set(int pos, int value) {

    checkIndex(pos);
    elem[pos] = value;
}

删除第一次出现的关键字 key

public boolean remove(int toRemove) {
    int index = indexOf(toRemove);
    if(index == -1) {
        System.out.println("没有这个数据");
        return false;
    }
    for (int i = index;i < usedSize;i++) {
        elem[i] = elem[i + 1];
    }
    usedSize--;
    elem[usedSize] = 0;
    return true;
}

获取顺序表长度

public int size() {
    return usedSize;
}

清空顺序表

public void clear() {
    usedSize = 0;
}

ArrayList

在集合框架中 , ArrayList 是一个普通的类 , 实现了 List接口

  1. ArrayList 是以泛型方式实现的 , 使用时必须先要实例化
  2. ArrayList 实现了 RandomAccess 接口 , 表名 ArrayList 支持随机访问
  3. ArrayList 实现了 Clonable 接口 , 表名ArrayList 是可以 clone的
  4. ArrayList 实现了Serializable 接口 , 表名ArrayList 是支持序列化的
  5. 和 Vector 不同 , ArrayList不是线程安全的 , 在单线程下可以使用 , 在多线程中可以选择 Vector 或者 CopyOnWriteList
  6. ArrayList 底层是一段连续的空间 , 并且可以动态扩容 , 是一个动态类的顺序表

创建ArrayList

public static void main(String[] args) {
	//构造一个空的列表
    ArrayList<Integer> arraylist1 = new ArrayList<>();
    //构造一个容量为十的列表
    ArrayList<Integer> arraylist2 = new ArrayList<>(10);
}

遍历ArrayList

三种方式进行遍历 :

  1. for 循环

    for (int i = 0; i < list.size(); i++) {
        System.out.print(list.get(i) + " ");
    }
    
  2. foreach

    for (Integer x : list) {
        System.out.print(x + " ");
    }
    System.out.println();
    
  3. 迭代器

    ListIterator<Integer> it = list.listIterator();
    while(it.hasNext()) {
        System.out.print(it.next()+" ");
        //打印的同时 让 it 往前走一步
    }
    

ArrayList 操作

public static void main(String[] args) {
    ArrayList<String> arrayList = new ArrayList<>();
    arrayList.add("张三");
    arrayList.add("王五");
    arrayList.add("李四");
    System.out.println(arrayList);

    //获取 arrayList 中的有效元素个数
    System.out.println(arrayList.size());

    //获取和设置 index 位置上的元素 , index必须介于 [0,size)之间
    System.out.println(arrayList.get(0));
    arrayList.set(0,"赵六");
    System.out.println(arrayList.get(0));

    //在arrayList 的index 位置插入指定元素 , index及后续的元素同一往后挪一个位置
    arrayList.add(1,"刘七");
    System.out.println(arrayList);

    //删除指定元素 , 找到了就删除 , 该元素之后的元素同一往前挪一个位置
    arrayList.remove("赵六");
    System.out.println(arrayList);

    //删除arrayList中index位置上的元素 , 注意 index不要超过list中有效元素个数 , 否则会抛出下标越界异常
    arrayList.remove(arrayList.size()-1);
    System.out.println(arrayList);


}

例题

杨辉三角

在这里插入图片描述
在这里插入图片描述

public List<List<Integer>> gengrate(int numRows) {
    List<List<Integer>> ret = new ArrayList<>();
    List<Integer> row = new ArrayList<>();
    row.add(1);
    ret.add(row);
    for (int i = 0; i < numRows; i++) {
        List<Integer> prevRom = ret.get(i - 1);
        List<Integer> curRom = new ArrayList<>();
        
        curRom.add(1);//第一个1

        //中间 curRow list 的值
        for (int j = 0; j < i; j++) {
            int x = prevRom.get(j) + prevRom.get(j - 1);
            curRom.add(x);
        }

        curRom.add(1);//最后一个1
        ret.add(curRom);
    }
    return ret;
}
删除多余字符
/**
 * s1 = welcome to home
 * s2 = come
 * 要求删除 s1 中的字符 , 这些字符都是 s2 出现的 s1 = wl t h
 * @param args
 */
public static void main(String[] args) {
    ArrayList<Character> list = new ArrayList<>();
    String s1 = "welcome to home";
    String s2 = "come";

    for (int i = 0; i < s1.length(); i++) {
        char ch = s1.charAt(i);
        if (!s2.contains(ch + "")) {
            list.add(ch);
        }
    }
    for (int i = 0; i < list.size(); i++) {
        System.out.print(list.get(i));

    }

}
总结

优点 : 当给定下标时 , 查找速度非常快 . 适合给定下标的查找

缺点 :
1. 插入 : 必须挪动元素 , 才能插入元素
2. 删除 : 必须挪动元素 , 才能删除
3. 每次扩容 , 非常浪费资源

);
if (!s2.contains(ch + “”)) {
list.add(ch);
}
}
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i));

}

}


#### 总结

优点 : 当给定下标时 , 查找速度非常快 . 适合给定下标的查找

缺点 : 1. 插入 : 必须挪动元素 , 才能插入元素

			2. 删除 : 必须挪动元素 , 才能删除
   			3. 每次扩容 , 非常浪费资源































































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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值