بازگشت به درس

Output a single-linked list

اهمیت: 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 فقط یک پیمایش لیست است مانند 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);

حالا کدام بهتر است؟

از لحاظ فنی، حلقه مفیدتر است. این دو نوع یک کار را انجام می‌دهند اما حلقه منابع را برای فراخوانی‌های تودرتوی تابع مصرف نمی‌کند.

از سوی دیگر، نوع بازگشتی کوتاه‌تر است و بعضی اوقات برای فهمیدن راحت‌تر است.