學習軌道
/
Python
Python
/
練習
/
連結串列
連結串列

連結串列

中等

簡介

你正在參與一個專案,要為繁忙的鐵路網開發一套列車調度系統。

你接到的任務是為調度系統中的列車路線開發一個原型。 每條路線由一連串車站組成,也就是某一班列車沿途停靠的車站序列。

說明

你的團隊決定用雙向鏈結串列來表示時刻表上的每一條火車路線。火車路線上每一站,都會用鏈結串列中的一個節點來表示。

你不需要煩惱各站的抵達和出發時間。每一站單純用一個數字來表示就好。

路線可以延伸,在路線的開頭或結尾加入車站。路線也可以縮短,把開頭或結尾的車站移除。

有時候某個車站會關閉,這時就必須把這個車站從路線中移除,即使它不在路線的開頭或結尾也一樣。

路線的大小不是用火車行駛的距離來衡量,而是看它停靠幾站。

Note

鏈結串列是電腦科學中一種基礎的資料結構,也常用來實作其他資料結構。 顧名思義,它是一串彼此鏈結在一起的節點。 它是由「節點」組成的串列,每個節點會連接到它的一個或多個鄰居。 在單向鏈結串列中,每個節點只連接到它後面那個節點。 在雙向鏈結串列中,每個節點同時連接到它前面的節點和它後面的節點。

如果你想更深入了解鏈結串列,可以看看這篇文章,裡面用漂亮的圖解來說明。

這個練習在 Python 中的結構

連結串列可以用各種底層資料結構、各種方式來實作,不過這裡我們要求你以物件導向的方式來實作你的連結串列。

在起始檔案中,你會看到Node類別和LinkedList類別的開頭。 你的Node類別應該記錄自己的值,以及有哪些節點在它前面或後面。 你的push、pop、shift、unshift,以及len的特殊方法,都應該在LinkedList類別中實作。 你可能也會發現,為疊代實作一個特殊的iter方法很有用。

和核心練習不同,我們會對空的LinkedLists呼叫pop和shift來測試錯誤情況,所以你需要適當地raise錯誤。

最後,除了上面列出的方法之外,我們還希望你能實作delete。 delete會接受一個引數,也就是要從連結串列中移除的值。 如果這個值出現超過一次,只應移除第一個。


例外訊息

有時候我們必須引發例外。 這麼做的時候,你應該總是附上一則有意義的錯誤訊息,指出錯誤的來源是什麼。 這能讓你的程式碼更容易閱讀,也對除錯大有幫助。 如果你知道錯誤來源會是某種類型,可以選擇引發內建的錯誤類型之一,但仍然要附上有意義的訊息。

這個練習特別要求你使用 raise 敘述來「拋出」ValueError,表示要 delete() 的節點值不在連結串列中。 此外,如果已經沒有節點可以 pop(),就應該拋出 IndexError。 只有在你raise這些exceptions並附上訊息時,測試才會通過。

若要引發帶有訊息的ValueError,請把訊息寫成exception類型的引數:

# When the value passed to `delete()` is not found.
if not found:
    raise ValueError("Value not found")

若要引發帶有訊息的IndexError,請把訊息寫成exception類型的引數:

# When pop() is called and there are no nodes left in the linked list
if self.length == 0:
    raise IndexError("List is empty")

Python 的特殊方法

這個練習的測試也會對你的LinkedList呼叫len()。 為了讓len()能運作,你需要建立一個__len__特殊方法。 關於在 Python 中實作特殊方法或「dunder」方法的細節,請參閱Python 文件:基本物件自訂和Python 文件:object.len(self)。

我們也建議建立一個特殊的__iter__方法,幫助你疊代你的連結串列。



出處

經典的電腦科學主題
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Python Exercism

準備好開始 連結串列 了嗎?

註冊 Exercism,透過 17 個概念146 個練習 和真人引導來學習並精通 Python,全部免費。