標籤:資料結構 arraylist 順序表實現
線性表的順序儲存結構,也稱為順序表,指用一段連續的儲存單元依次儲存線性表中的資料元素。
根據順序表的特性,我們用數組來實現順序表,下面是我通過數組實現的Java版本的順序表。
package com.phn.datestructure;/** * @author 潘海南 * @Email [email protected] * @TODO 順序表 * @date 2015年7月16日 */public class FOArrayList<E> { // 順序表長度 private int size; // 順序表預設數組為null private Object[] data = null; // 順序表中數組的初始化長度 private int capacity; // 順序表預設初始化長度 private static final int DEFUALT_INITIAL_SIZE = 0; /** * 預設無參建構函式 */ public FOArrayList() { this(DEFUALT_INITIAL_SIZE); } /** * @TODO 帶參建構函式 * @param initialSize 初始化順序表長度 */ public FOArrayList(int initialSize) { if (initialSize < 0) { throw new RuntimeException("數組大小錯誤:" + initialSize); } this.data = new Object[initialSize]; this.capacity = initialSize; this.setSize(); } /** * @TODO 設定順序表的長度 */ private void setSize() { this.size = 0; } /** * @TODO 擷取順序表的長度 * @return size 順序表的長度 */ public int size() { return this.size; } /** * @TODO 順序表添加元素 * @param e 資料元素類型 * @return true */ public boolean add(E e) { ensureSize(size); this.data[size] = e; this.size++; return true; } /** * @TODO 順序表插入元素 * @param index 插入位置 * @param e 資料元素類型 * @return true */ public boolean insert(int index, E e) { if (index >= 0 && index <= size) { ensureSize(size); E temp = (E) this.data[index - 1]; this.data[index - 1] = e; this.size++; for (int i = index; i <= size; i++) { E temp2 = (E) this.data[i]; this.data[i] = temp; temp = temp2; } } else { throw new RuntimeException("數組下標錯誤:" + index); } return true; } /** * @TODO 順序表刪除元素 * @param index 將要刪除的元素的索引位置 * @return E 刪除的元素 */ public E remove(int index) { validateIndex(index); E e = (E) this.data[index]; for (int i = index; i < size - 1; i++) { this.data[i] = this.data[i + 1]; } this.size--; return e; } /** * @TODO 根據元素索引位置擷取元素 * @param index 元素的索引位置 * @return E 元素e */ public E get(int index) { validateIndex(index); return (E) this.data[index]; } /** * @TODO 將順序表中索引位置為i的元素修改為元素e * @param index 元素的索引位置 * @param e 需要修改成的元素 * @return true 修改成功標誌 */ public boolean set(int index, E e) { validateIndex(index); this.data[index] = e; return true; } @Override public String toString() { return this.arrayToString(data); } /** * @TODO 擷取字串形式的順序表中的數組序列 * @param a 順序表中的數組 * @return String 字串形式的順序表中的數組序列 */ private String arrayToString(Object[] a) { if (a == null) return "null"; int iMax = this.size - 1; if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); b.append(‘[‘); for (int i = 0;; i++) { b.append(String.valueOf(a[i])); if (i == iMax) return b.append(‘]‘).toString(); b.append(", "); } } /** * @TODO 驗證所給索引位置是否合法 * @param index 給出的索引位置 */ private void validateIndex(int index) { if (index >= this.size || index <= 0) { throw new RuntimeException("數組下標錯誤:" + index); } } /** * @TODO 判斷是否需要擴充順序表容量 * @param currentSize 當前順序表的大小 */ private void ensureSize(int currentSize) { if (currentSize == capacity) { this.capacity = (this.capacity * 3) / 2 + 1; Object[] newData = new Object[this.capacity]; for (int i = 0; i < currentSize; i++) { newData[i] = this.data[i]; } this.data = newData; } }}
主要注意上述3個私人成員變數,如下:
// 順序表長度private int size;// 順序表中數組的初始化長度private int capacity;// 順序表預設數組為nullprivate Object[] data = null;
如同注釋解釋的那樣,size用來表示順序表的長度,data用來表示數組,而capacity用來表示數組的長度.
相信data應該比較好理解,而對應的兩個長度變數相對難理解一些,下面解釋一下:
- size指的是對外界訪問這個順序表的長度時展示的值,是順序表中資料元素的個數,隨順序表插入和刪除操作而會進行改變;
- capacity表示的是data數組的長度,實際上也是整個順序表的容量,在順序表初始化的時候可以賦值,或者之後可以調用順序表的擴容來進行改變;
- size是小於等於capacity的。
這裡主要講講順序表的插入和刪除:
順序表的插入示範:
根據圖片可以看出插入一個元素後,插入位置之後的元素都需要向後移動一個位置。
刪除操作則是插入操作的逆過程,刪除位元置之後的元素都需要向前移動一個位置。
時間複雜度分析:
- 在順序表進行存入,尋找和修改時,平均時間複雜度都是O(1);
- 而在進行插入和刪除操作時,最快時為O(1),最慢時為O(n),所以平均時間複雜度為O(n)。
解釋:上述的存入和插入有區別,存入表示儲存在數組末尾,而插入表示插入在任意位置。
優缺點分析:
優點:
- 不用為表示表中資料元素之間的邏輯關係而增加額外的儲存空間;
可以快速的存取表中任意位置的元素。
缺點:
插入和刪除操作需要移動大量元素;
- 當線性表的長度變化較大的時候,很難確定儲存空間的容量;
- 容易造成儲存空間的“片段”。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Java資料結構-線性表之順序表ArrayList