擁抱「資料結構」的「演算法」(02) - 陣列 Array
前言
今天要來介紹第一種資料結構:陣列,算是最淺顯易懂的一種線性串列
,從字面上的意思來看,大概可以猜出,資料會排成一列一列的,一起來觀察一下生活中的例子吧
生活常識
在生活中有沒有什麼東西是排成一列一列的呢?像是排隊買口罩XD,還是像書一本一本的排列在書櫃裡,建築一棟房子或是搭乘捷運、火車、高鐵,好像都觀察到排列的情形
而我自己是想到了一個有趣的經驗,大家有沒有去便利商店買過飲料,從擺滿各式各樣飲料的冰箱裡,拿出一罐飲料時,請你回想一下那個畫面,有沒有發生什麼有趣的現象,除了手上會多一罐飲料之外,冰箱裡面會發生什麼事情呢?如果覺得滿頭問號的話,可以參考一下我拍的影片哦~從影片中可以觀察到,當第一罐飲料被拿走時,其他飲料會自動往前遞補,這樣的冰箱設計是不是很神奇!
在生活中充滿了許多排列的例子,但在電腦世界裡,資料的排列又是如何進行的?有沒有什麼令人驚豔的特別之處呢?讓我們一同來瞭解看看吧!
專業知識 - 陣列 Array
雖然從字面上的意思,感覺是資料排成一列一列的,但其實 陣列
還有其他的特性與限制
1. 可以用來儲存
一群相同類型
的資料
2. 會使用一段連續
的記憶體空間來存放
3. 必須明確定義
要存放多少數量
的資料
4. 可透過索引
快速存取資料
5. 不方便做資料的追加與刪除
可能看文字描述會覺得文謅謅的,所以一樣舉生活例子,一個禮拜有 7 天,小美想要在每一天都吃不同的保健食品,他考慮買個藥盒,裡面裝著每一天分配好的保健品,方便提醒自己
圖片來源 : momo
一個盒子總共有 7 個格子,分別代表週一到週六週日,小美做了以下的安排:
把上述例子套用在資料結構的陣列中,會變成下面這樣:
1. 可以用來儲存一群相同類型的資料
盒子可以拿來裝保健食品,保健食品就是一種類型(不會拿去裝安眠藥、感冒藥,誤食可能會影響上班狀態)
2. 會使用一段連續的記憶體空間來存放
有一排連續的格子可以提供空間來存放保健食品
3. 必須明確定義要存放多少數量的資料
總共有7格,分別可以7種保健食品 (如果數量隨時都會有增有減,無法明確定義的話,那會推薦改用其他種資料結構,後續會介紹)
4. 可透過索引快速存取資料
如果今天是週一,就可以直接找到寫著週一的格子,直接把保健品全部吃掉就可以了,不用像傳統作法,可能會帶7大罐保建食品去公司的抽屜放,抽屜還亂七八糟,吃的時候還要花心思找XD
5. 不方便做記憶體空間的追加與刪除
如果吃了一段時間,想要調整保健品的順序,例如週一要改吃維他命C,週五改吃B群,那會發現,整個盒子的內容物可能需要大搬風,或者要將保健食品拿出來並做一些調整,十分麻煩,如下表,全部的保健品都要全部拿出來重放了
當盒子太小
當今天想在多吃一些新的保健食品,但盒子只有 7 個格子,也會有大麻煩,由於盒子在開發製造的時候,就一體成形,可能只能買新的盒子
了
當盒子太大
如果今天想要換成 6 格,就會比較麻煩,那要看能不能把多的格子拿鋸子鋸掉XD,不然多那一格放著不用也是顯得浪費或是占空間,亦或是在買一個新的盒子內含6格,不論如何,就是不方便!
索引 vs 值
那回到電腦的記憶體中,陣列又是如何存放這些資料的呢?我們在宣告產生一個陣列變數時,就會產生一段連續的空間,並透過索引去存取該空間的值,索引初始位置從 0 開始,就如同藥盒在生產時,就明確的製造出7格連續的格子可以存放保健品
索引初始位置從 0 開始
索引初始位置從 0 開始
索引初始位置從 0 開始
我們來看看以 C# 的方式,會如何新增或存取陣列,首先,先宣告一個名稱為 box,型態是陣列的變數,陣列長度為 7 ,可以用來存放文字,接著將每一種保健食品分別寫入相對應的
索引
中變數名稱[索引位置] = 要存放的值
變數名稱[索引位置] = 要存放的值
變數名稱[索引位置] = 要存放的值
var box = new string[7]; //不多也不少,就是只有7個空間
box[0] = "維他命D"; //變數名稱[索引位置] = 要存放的值
box[1] = "葉黃素";
box[2] = "蔓越莓錠";
box[3] = "B群";
box[4] = "綜合維他命";
box[5] = "益生菌";
box[6] = "維他命C";
如果要透過程式,了解小美
週三
吃什麼保健食品,要怎麼做呢,變數名稱[索引位置]
變數名稱[索引位置]
變數名稱[索引位置]
使用 box[2]
來存取,就會得到小美週三固定會吃蔓越莓錠
當陣列太小
當陣列不夠用時,那就要新宣告變數來存放資料,因為陣列必須使用連續的記憶體
,當 box 的陣列長度只有 7 的時候,你無法確定記憶體中第 8 格有沒有被其他人使用了,所以只好透過宣告一個新變數的方式
var newBox = new string[8];
這時候電腦找一段連續的記憶體空間,然後你要自己將 box 內的值逐一搬到 newbox 裡面去,是不是很麻煩呢XD
當陣列太大
當陣列有多餘的空間時,一樣要新宣告變數,再將 box 內的值逐一搬到 newbox 裡面去
var newBox = new string[6];
透過上述情況,可以得知陣列的長度再宣告的時候就會被固定,後續的增減都會麻煩許多,所以請大家在使用陣列時,一定審慎評估
今日小結
陣列在生活中的例子就很像是一體成型的汽車或冰箱,當可收納的空間不足的時候,就需要汰舊換新,但這種情況很少年,可能好幾年或好幾十年才會遇到一次。在電腦世界中,陣列適合存放固定數量的資料,且可以透過索引快速存取,如果數量會常常遇到增減,或是資料常常會有
大搬風的需求,那麼就要考慮使用其他類型的資料結構。常使用到陣列的例子,像是統計一篇英文文章中,a-z出現的次數,因為我們很確定英文字母最多就是 26 個,不會有 27 或 28 個,所以我們就可以宣告一個長度為 26 的陣列去做數量的統計
var letters = new int[26];
如果想要知道字母 A 出現幾次就可以呼叫 letters[0], 想要知道字母 Z 出現幾次就可以呼叫 letters[25]
每日解謎
圖片來源:https://unsplash.com/photos/r2PBy6dWJE0
因為報復性消費,本旅社最近入住率100%,目前總共有10間房間,通通客滿
房號 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
姓名 | A 小姐 | c 先生 | e 先生 | r 小姐 | Y 先生 | F 小姐 | R 先生 | z 先生 | G 小姐 | a 先生 |
就在今天下午,第 2、3、6、8、9 間的房客紛紛辦理退房,而就在此時此刻,有一些房客提出想換房間的要求,因為他們都是超級VVIP,一定要辦理,但他們留下了神祕的訊息,似乎在考驗你什麼,你能解讀嗎?
house[1] = house[3];
house[3] = "";
house[2] = house[6];
house[6] = "";
house[3] = house[9];
house[9] = "";
在終於忙完所有事項之後,你有沒有發現什麼隱藏的訊息呢?歡迎留言哦XD
留言
張貼留言