Output a single-linked list
بیایید فرض کنیم یک لیست پیوندی داریم (همانطور که در فصل بازگشت و پشته توضیح داده شد):
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
فقط یک پیمایش لیست است مانند i
در حلقه for
.
راهحل بازگشتی
نوع بازگشتی 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); // نمایش المان کنونی
if (list.next) {
printList(list.next); // انجام کار یکسان برای بقیهی لیست
}
}
printList(list);
حالا کدام بهتر است؟
از لحاظ فنی، حلقه مفیدتر است. این دو نوع یک کار را انجام میدهند اما حلقه منابع را برای فراخوانیهای تودرتوی تابع مصرف نمیکند.
از سوی دیگر، نوع بازگشتی کوتاهتر است و بعضی اوقات برای فهمیدن راحتتر است.