1. 程式人生 > >數據結構學習筆記(一)數組

數據結構學習筆記(一)數組

於平 style 動態 clas ram 添加元素 二次 pan exception

基本概念

所謂數組,是有序的元素序列。也就是把數據碼成一排存放的一種結構。

最大的優點

快速查詢,根據索引可以快速查找相應的元素

二次封裝自己的數組

一個數組應該具備的功能(並不固定,還可以擴充一些功能)

  • 獲取數組的初始容量
  • 獲取數組中元素的個數
  • 判斷數組是否為空
  • 添加元素
    • 在數組首部添加元素
    • 在數組尾部添加元素
    • 在數組指定位置添加元素
  • 刪除元素
    • 刪除數組首部元素
    • 刪除數組尾部元素
    • 刪除數組指定位置元素
    • 刪除數組中某一個元素
  • 修改元素
  • 查找元素
    • 判斷元素是否存在
    • 查找元素對應的索引
/**
 * 動態數組--泛型使其支持任意類型的數據
 * @param <E>
 
*/ public class Array<E> { private E[] data; private int size;//數組中元素的個數 //構造函數--創建一個指定容量的數組 public Array(int capacity) { data = (E[]) new Object[capacity]; size = 0; } //無參構造--默認創建一個容量為10的數組 public Array() { this(10); } //獲取數組中元素的個數 public
int getSize() { return size; } //獲取數組的容量 public int getCapacity() { return data.length; } //判斷數組是否為空 public boolean isEmpty() { return size == 0; } //在數組尾部添加元素 public void addLast(E e) { add(size, e); } //在數組首部添加元素 public void
addFirst(E e) { add(0, e); } //在指定位置添加元素 public void add(int index, E e) { if (size == data.length) resize(2 * data.length); //擴容2倍大小--思路就是把原來數組中的數據放到一個新的數組中 if (index < 0 || index > size) throw new IllegalArgumentException("add fail, Required index >=0 && index <=size"); for (int i = size - 1; i >= index; i--) data[i + 1] = data[i]; data[index] = e; size++; } //查詢數組某個位置的元素 public E get(int index) { if (index < 0 || index > size) throw new IllegalArgumentException("get fail, index is illegal"); return data[index]; } //設置數組某個位置的元素 public void set(int index, E e) { if (index < 0 || index >= size) throw new IllegalArgumentException("set fail, index is illegal"); data[index] = e; } //查詢數組中是否存在元素e public boolean contains(E e) { for (int i = 0; i < size; i++) { if (data[i] == e) return true; } return false; } //查詢數組中是否存在元素e 存在則返回第一個索引 public int find(E e) { for (int i = 0; i < size; i++) { if (data[i].equals(e)) return i; } return -1; } //查詢數組中是否存在元素e 存在則返回全部索引 public int findAll(E e) { return -1; } //刪除數組中index位置的元素並返回 public E remove(int index) { if (index < 0 || index >= size) throw new IllegalArgumentException("remove fail, index is illegal"); E ret = data[index]; for (int i = index + 1; i < size; i++) data[i - 1] = data[i]; size--; data[size] = null;//使用泛型後 數組中size位置存放的是類對象的引用 手動釋放空間 if (size == data.length / 4 && data.length / 2 !=0) //防止復雜度震蕩--以及數組長度為1的情況--在數組滿的情況添加元素後又刪除元素 resize(data.length / 2); //縮容 return ret; } //刪除數組中第一個元素 public E removeFirst() { return remove(0); } //刪除數組中最後一個元素 public E removeLast() { return remove(size - 1); } //數組中如果存在一個元素,則進行刪除一個 public void removeElement(E e) { int index = find(e); if (index != -1) remove(index); } //數組中如果存在元素,則進行全部刪除 public void removeAllElement(E e) { int index; do { index = find(e); if (index != -1) remove(index); } while (index != -1); } //重寫toString方法 @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(); } //數組長度動態變化 private void resize(int newCapacity) { E[] newData = (E[]) new Object[newCapacity]; for (int i = 0; i < size; i++) newData[i] = data[i]; data = newData; } }

復雜度分析

什麽是時間復雜度這裏看另外一篇文章https://blog.csdn.net/qq_41523096/article/details/82142747

  • 添加元素---O(n)-------復雜度分析一般考慮最壞的情況
    • 在數組首部添加元素---addFirst(e)---O(n)---因為向數組頭添加元素 需要把每個元素向後挪
    • 在數組尾部添加元素---addLast(e)---O(1)
    • 在數組指定位置添加元素--add(index,e)---O(n/2)=O(n)---平均的情況下添加元素每次需要挪n/2個元素
    • 擴容resize()---O(n)--最壞情況
  • 刪除元素---O(n)
    • 刪除數組首部元素---removeFirst()---O(n)
    • 刪除數組尾部元素----removeLast(e)---O(1)
    • 刪除數組指定位置元素------remove(index,e)---O(n/2)=O(n)
    • 縮容resize()---O(n)--最壞情況
  • 修改元素---set(index,e)---已知索引是O(1)---未知索引是O(n)--因為需要遍歷數組中每一個元素
  • 查找元素---已知索引是O(1)---未知索引是O(n)--因為需要遍歷數組中每一個元素
    • 根據索引查找元素---get(index)--O(1)
    • 判斷元素是否存在---contains(e)---O(n)---因為需要遍歷數組中每一個元素
    • 查找元素對應的索引---find(e)---O(n)
  • 容量動態變化resize()--不應該考慮最壞情況,這是不合理的,因為不可能每次都觸發這個方法--均攤復雜度

假設數組容量是8,使用addLast()方法需要9次操作才觸發一次resize(轉移8個元素到新數組),一共17次操作,相當於平均每次addLast,進行2次操作,所以均攤計算它的復雜度是O(1);

同理removeLast也是O(1); 同時考慮這兩個方法,特殊情況當添加一個元素觸發了擴容,然後有刪除這個元素觸發縮容,造成復雜度震蕩.解決方法Lazy 也就是縮容的時候不用那麽急

數據結構學習筆記(一)數組