iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
自我挑戰組

資料結構與演算法-CS61B學習筆記系列 第 4

Day04-AList (solve ArrayList size issue)

  • 分享至 

  • xImage
  •  

這章節來探討AList,array list的意思。

首先提到當我們要使用get(index)從list中拿出元素時,SLList就會比AList慢,因為SLList的結構會需要從各個node開始慢慢去追尋到目標index的node;而AList因為有紀錄index,所以不管list長度有多長,都可以瞬間提取出目標index的元素。

再來提到removeLast:

public class AList{
	int[] items;
	int size;

	public AList(){
		items = new int[100];
		size = 0;
	}
	
	public void addLast(int item){
		items[size] = item;
		size += 1;
	}

	public int getLast(){
		return items[size - 1];
	}
	
	public int removeLast(){
		int lastItem = getLast();
		// items[size - 1] = 0;
	  size -= 1;
	  return lastItem;
  }
}

直覺上會認為既然要remove那應該真的去做items[size - 1] = 0這行,真的把最後一個元素消滅掉,但其實還有另一種做法,就是改變size即可。

因為我們有用AList包裹起來,裏頭的操作只要能符合使用AList的期待就行;這代表說我們在removeLast的時候其實只要更改size就好了,不用真的把最後一個元素從items中消滅掉,因為我們的addLast或者getLast其實也都是透過size來操作的。

接著就是重頭戲了,因為array的特性勢必得在初始化的時候指定一個長度,當我們要塞進的元素數量超過初始化長度該如何處理呢?

其實也沒有什麼神奇的做法,就是必須得在碰到邊界值時把array加大。所以接著該討論的問題是,我們可以有哪些加大的策略?

首先第一個方法是直接把長度加倍,這也是python的做法:

public class AList{
...
	public void addLast(int item){
			if(size == items.length){
				int[] temp = new int[size * 2];
				System.arraycopy(items, 0, temp, 0, size);
				items = temp;
			}
			items[size] = item;
			size += 1;
	}
...
}

但是這樣還是會有個問題,就是記憶體上的空間有點浪費,假設我們一口氣add了100萬的元素,接著又刪除了90萬個元素,就變成有閒置的90萬個空間佔在那邊。這時就需要去考量usage ratio的問題:

R = size / items.length

size是實際儲存了多少個元素,items.length是array佔了多少記憶體空間。有個經驗法則是說當

R < 0.25時,那就要把items減半。

license
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License


上一篇
Day03-DLList (solve addLast issue)
下一篇
Day05-Asymptotics
系列文
資料結構與演算法-CS61B學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言