輸出單向連結串列
重要性:5
假設我們有一個單向連結串列(如章節中所述 遞迴與堆疊)
let list = {
value: 1,
next: {
value: 2,
next: {
value: 3,
next: {
value: 4,
next: null
}
}
}
};
撰寫一個函式 printList(list)
來逐一輸出串列項目。
使用迴圈和遞迴製作兩個版本的解答。
哪個比較好:使用遞迴或不使用遞迴?
基於迴圈的解答
基於迴圈的解決方案變體
let list = {
value: 1,
next: {
value: 2,
next: {
value: 3,
next: {
value: 4,
next: null
}
}
}
};
function printList(list) {
let tmp = list;
while (tmp) {
alert(tmp.value);
tmp = tmp.next;
}
}
printList(list);
請注意,我們使用一個臨時變數 tmp
來遍歷清單。技術上來說,我們可以使用函式參數 list
代替
function printList(list) {
while(list) {
alert(list.value);
list = list.next;
}
}
…但那樣做是不明智的。在未來,我們可能需要擴充函式,對清單執行其他操作。如果我們變更 list
,那麼我們就會失去這樣的功能。
談到好的變數名稱,這裡的 list
就是清單本身。它的第一個元素。它應該保持這樣。這很清楚且可靠。
從另一方面來說,tmp
的角色是專門用來遍歷清單,就像 for
迴圈中的 i
一樣。
遞迴解法
printList(list)
的遞迴變體遵循一個簡單的邏輯:要輸出一個清單,我們應該輸出目前的元素 list
,然後對 list.next
執行相同的操作
let list = {
value: 1,
next: {
value: 2,
next: {
value: 3,
next: {
value: 4,
next: null
}
}
}
};
function printList(list) {
alert(list.value); // output the current item
if (list.next) {
printList(list.next); // do the same for the rest of the list
}
}
printList(list);
現在哪個比較好?
技術上來說,迴圈比較有效率。這兩個變體執行相同的工作,但迴圈不會花費資源在巢狀函式呼叫上。
從另一方面來說,遞迴變體比較簡潔,有時也比較容易理解。