继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

玩转数据结构之数组

侠客岛的含笑
关注TA
已关注
手记 133
粉丝 1.6万
获赞 1807

Where to use Data structure?

图片描述

Data structure

图片描述

Why learn data structure?

  • Get the top company's offer
  • Better coding
  • Change the world

注意事项

Pythonic的写法可能比逻辑本身更重要, 当然,其他语言也有类似的情况。

arr[]
for i in range(10)
    arr.append(i)
效率低
arr = [i for i in range(10)]

Array

public class Main {

    public static void main(String[] args) {

        int[] arr = new int[10];
        for(int i = 0 ; i < arr.length ; i ++)
            arr[i] = i;

        int[] scores = new int[]{100, 99, 66};
        for(int i = 0 ; i < scores.length ; i ++)
            System.out.println(scores[i]);
        // 数组有可变力(可迭代)的能力
        for(int score: scores)
            System.out.println(score);

        scores[0] = 96;

        for(int i = 0 ; i < scores.length ; i ++)
            System.out.println(scores[i]);
    }
}

然后我看了下class文件

int[] var8 = scores;
        int var4 = scores.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            int score = var8[var5];
            System.out.println(score);
        }

封装自定义数组

图片描述


public class Array {
    // E代表数据类型
    private E[] data;
    private int size;

    // 构造函数,传入数组的容量capacity构造Array
    public Array(int capacity){
        data = (E[])new Object[capacity];
        size = 0;
    }

    // 无参数的构造函数,默认数组的容量capacity=10
    public Array(){
        this(10);
    }

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

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

    // 返回数组是否为空
    public boolean isEmpty(){
        return size == 0;
    }

    // 在index索引的位置插入一个新元素e
    public void add(int index, E e){

        if(index < 0 || index > size)
            throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size.");

        if(size == data.length)
            resize(2 * data.length);

        for(int i = size - 1; i >= index ; i --)
            data[i + 1] = data[i];

        data[index] = e;

        size ++;
    }

    // 向所有元素后添加一个新元素
    public void addLast(E e){
        add(size, e);
    }

    // 在所有元素前添加一个新元素
    public void addFirst(E e){
        add(0, e);
    }

    // 获取index索引位置的元素
    public E get(int index){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Get failed. Index is illegal.");
        return data[index];
    }

    public E getLast(){
        return get(size - 1);
    }

    public E getFirst(){
        return get(0);
    }

    // 修改index索引位置的元素为e
    public void set(int index, E e){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Set failed. Index is illegal.");
        data[index] = e;
    }

    // 查找数组中是否有元素e
    public boolean contains(E e){
        for(int i = 0 ; i < size ; i ++){
// equals是值比较,==是引用比较
            if(data[i].equals(e))
                return true;
        }
        return false;
    }

    // 查找数组中元素e所在的索引,如果不存在元素e,则返回-1
    public int find(E e){
        for(int i = 0 ; i < size ; i ++){
            if(data[i].equals(e))
                return i;
        }
        return -1;
    }

    // 从数组中删除index位置的元素, 返回删除的元素
    public E remove(int index){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Remove failed. Index is illegal.");

        E ret = data[index];
        for(int i = index + 1 ; i < size ; i ++)
            data[i - 1] = data[i];
        size --;
        data[size] = null; // loitering objects != memory leak 删除size指向的引用。java回收机制就能
           // 当我们使用泛型时,数组中存储的时一个一个的引用。当数组中还存在着一个对象的引用的话,就不会被java自动回收机制所回收
        if(size == data.length / 4 && data.length / 2 != 0)
            resize(data.length / 2);
        return ret;
    }

    // 从数组中删除第一个元素, 返回删除的元素
    public E removeFirst(){
        return remove(0);
    }

    // 从数组中删除最后一个元素, 返回删除的元素
    public E removeLast(){
        return remove(size - 1);
    }

    // 从数组中删除元素e
    public void removeElement(E e){
        int index = find(e);
        if(index != -1)
            remove(index);
    }
    // 从数组删除所有元素e
   public boolean removeAlllElement(E e){
        int index = find(e);
      for(int i = 0;i < size;i++){
            if(index != -1){
                remove(index);
                }
            }
        return true;
 }      
    @Override
    public String toString(){

        StringBuilder res = new StringBuilder();
        res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length));
        res.append('[');
        for(int i = 0 ; i < size ; i ++){
            res.append(data[i]);
            if(i != size - 1)
                res.append(", ");
        }
        res.append(']');
        return res.toString();
    }

    // 将数组空间的容量变成newCapacity大小
    private void resize(int newCapacity){

        E[] newData = (E[])new Object[newCapacity];
        for(int i = 0 ; i < size ; i ++)
            newData[i] = data[i];
        data = newData;
    }
}

Test Example

图片描述

泛型

图片描述

动态数组

图片描述

大概思路就是达到临界值(增加数组容量或者减少数组容量)生成一个新数组,然后内容迁移,最后指向新数组

时间复杂度

图片描述
图片描述

均摊 amortized time complexity

图片描述

复杂度震荡

图片描述

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP

热门评论

写的很棒,好想复制呀。。。

查看全部评论