0Pricing
TypeScript Academy · บทเรียน

การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้

จำลองโหนดต้นไม้ที่ซ้อนกันด้วยชนิดข้อมูลแบบเรียกซ้ำ

การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้ เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

ชนิดโหนดของทรี

ทรีเป็นการขยายแนวคิดจากลิสต์ โดยแต่ละโหนดมีค่าและอาร์เรย์ของโหนดย่อยที่เป็นชนิดเดียวกัน นี่คือชนิดแบบเรียกตัวเองที่มีอาร์เรย์ children

type TreeNode<T> = {
  value: T;
  children: TreeNode<T>[];
};
const leaf: TreeNode<number> = { value: 1, children: [] };
console.log(leaf.value);

สร้างทรีขนาดเล็ก

โหนดที่มีโหนดย่อยเป็นเพียงออบเจกต์ที่ซ้อนกัน อาร์เรย์ว่างเป็นกรณีฐานตามธรรมชาติของ leaf

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
const tree: TreeNode<string> = {
  value: "root",
  children: [
    { value: "a", children: [] },
    { value: "b", children: [] }
  ]
};
console.log(tree.children.length);

ซ้อนให้ลึกยิ่งขึ้น

โหนดย่อยสามารถมีโหนดย่อยของตัวเองได้ลึกเท่าใดก็ได้ เพราะ child แต่ละโหนดเป็น TreeNode ที่สมบูรณ์ในตัวเอง

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
const tree: TreeNode<number> = {
  value: 1,
  children: [
    { value: 2, children: [{ value: 4, children: [] }] },
    { value: 3, children: [] }
  ]
};
console.log(tree.children[0].children[0].value);

หาผลรวมของค่าทั้งหมด

ฟังก์ชันแบบเรียกตัวเองจะเยี่ยมชมแต่ละโหนดและเรียกตัวเองเข้าไปยังโหนดย่อย พร้อมสะสมผลลัพธ์ ซึ่งเป็นการเดินผ่านแบบความลึกก่อน

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function sum(node: TreeNode<number>): number {
  let total = node.value;
  for (const child of node.children) total += sum(child);
  return total;
}
const t: TreeNode<number> = { value: 1, children: [{ value: 2, children: [] }, { value: 3, children: [] }] };
console.log(sum(t));

นับจำนวนโหนด

รูปแบบการเดินผ่านเดียวกันนี้ใช้สำหรับนับโหนดได้ โดยนับโหนดปัจจุบันหนึ่งโหนดรวมกับจำนวนโหนดของทรีย่อยทั้งหมด

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function count<T>(node: TreeNode<T>): number {
  return 1 + node.children.reduce((acc, c) => acc + count(c), 0);
}
const t: TreeNode<string> = { value: "r", children: [{ value: "a", children: [] }] };
console.log(count(t));

การค้นหาความลึกสูงสุด

ความลึกเท่ากับหนึ่งบวกกับความลึกสูงสุดของโหนดลูก หรือเท่ากับหนึ่งสำหรับโหนดใบที่ไม่มีโหนดลูก

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function depth<T>(node: TreeNode<T>): number {
  if (node.children.length === 0) return 1;
  return 1 + Math.max(...node.children.map(depth));
}
const t: TreeNode<number> = { value: 1, children: [{ value: 2, children: [{ value: 3, children: [] }] }] };
console.log(depth(t));

การรวบรวมค่าทั้งหมด

ทำให้ต้นไม้เป็นอาร์เรย์แบบแบนราบ โดยนำค่าปัจจุบันมาต่อกับโหนดลูกที่ทำให้เป็นอาร์เรย์แบบแบนราบแล้ว

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function flatten<T>(node: TreeNode<T>): T[] {
  return [node.value, ...node.children.flatMap(flatten)];
}
const t: TreeNode<number> = { value: 1, children: [{ value: 2, children: [] }, { value: 3, children: [] }] };
console.log(flatten(t));

การค้นหาในต้นไม้

การค้นหาแบบเรียกซ้ำจะส่งคืนโหนดแรกที่ตรงตามเงื่อนไขตรวจสอบ และจะสำรวจโหนดลูกเมื่อโหนดปัจจุบันไม่ตรงกัน

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function find<T>(node: TreeNode<T>, pred: (v: T) => boolean): TreeNode<T> | null {
  if (pred(node.value)) return node;
  for (const c of node.children) {
    const hit = find(c, pred);
    if (hit) return hit;
  }
  return null;
}
const t: TreeNode<number> = { value: 1, children: [{ value: 5, children: [] }] };
console.log(find(t, v => v === 5)?.value);

การแปลงค่าในต้นไม้

แปลงค่าทุกค่าโดยยังคงโครงสร้างเดิมไว้ ด้วยการแปลงค่าและโหนดลูกแบบเรียกซ้ำ

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function mapTree<T, U>(node: TreeNode<T>, fn: (v: T) => U): TreeNode<U> {
  return { value: fn(node.value), children: node.children.map(c => mapTree(c, fn)) };
}
const t: TreeNode<number> = { value: 1, children: [{ value: 2, children: [] }] };
console.log(mapTree(t, x => x * 100).value);

ต้นไม้จำลองข้อมูลจริง

ระบบไฟล์ ต้นไม้ DOM แผนผังองค์กร และต้นไม้ไวยากรณ์นามธรรม ล้วนเป็นต้นไม้ทั้งสิ้น ชนิดข้อมูลแบบเรียกซ้ำชนิดเดียวสามารถอธิบายทั้งหมดได้พร้อมความปลอดภัยด้านชนิดข้อมูลอย่างครบถ้วน

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
type FileTree = TreeNode<string>;
const fs: FileTree = { value: "/", children: [{ value: "home", children: [] }] };
console.log(fs.value, fs.children[0].value);

โหนดใบและกิ่ง

โหนดจะเป็นโหนดใบเมื่อ children ว่าง และเป็นกิ่งในกรณีอื่น ความแตกต่างนี้มักเป็นตัวกำหนดตรรกะการท่องผ่านโครงสร้าง

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function isLeaf<T>(node: TreeNode<T>): boolean {
  return node.children.length === 0;
}
console.log(isLeaf({ value: 1, children: [] }));

ตรวจสอบความเข้าใจอย่างรวดเร็ว: โครงสร้างต้นไม้

ทดสอบความเข้าใจเกี่ยวกับการกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้

สรุป: การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้

คุณจำลองต้นไม้ด้วย TreeNode<T> โดยแต่ละโหนดมีค่าและอาร์เรย์ของโหนดลูก จากนั้นเขียนฟังก์ชันแบบเรียกซ้ำเพื่อหาผลรวม นับ ค้นหา และแปลงค่าในโครงสร้างเหล่านั้น

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
const t: TreeNode<number> = { value: 1, children: [{ value: 2, children: [] }] };
console.log(t.children[0].value);

คำถามที่พบบ่อย

บทเรียน “การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้”

จำลองโหนดต้นไม้ที่ซ้อนกันด้วยชนิดข้อมูลแบบเรียกซ้ำ คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การกำหนดชนิดข้อมูลแบบเรียกซ้ำ
  2. การกำหนดชนิดข้อมูลให้โครงสร้างต้นไม้
  3. ชนิดข้อมูลค่า JSON
  4. ความลึกและขีดจำกัดของการเรียกซ้ำ
← กลับไปที่ TypeScript Academy