Skip to content

อัลกอริทึม (Algorithms)

อัลกอริทึม คือ ขั้นตอนหรือกระบวนการที่ใช้ในการแก้ปัญหาหรือดำเนินการกับข้อมูลอย่างเป็นระบบ สามารถแบ่งออกเป็นกลุ่มหลัก ๆ ดังนี้:

อัลกอริทึมพื้นฐาน (Basic Algorithms)

Sequential Algorithm (อัลกอริทึมแบบลำดับ)

การทำงานเรียงตามลำดับทีละขั้นตอนจากต้นจนจบ โดยไม่มีการข้ามขั้นตอนใด ๆ

ts
// FP: Breakfast steps as a pipeline
const makeBreakfast = () =>
  [boilWater, addTeaBag, pourInCup, addSugar].reduce((acc, fn) => fn(acc), undefined);

Selection Algorithm (อัลกอริทึมแบบเลือกทาง)

การตัดสินใจเลือกทางเดินของโปรแกรมตามเงื่อนไขที่กำหนด

ts
// FP: Weather check as a pure function
const checkWeather = (temp: number): string =>
  temp > 30 ? "Very hot, stay indoors"
  : temp > 25 ? "Nice weather"
  : "Cool weather";

Iteration Algorithm (อัลกอริทึมแบบวนซ้ำ)

การทำงานซ้ำ ๆ ในรูปแบบของลูป จนกว่าจะถึงเงื่อนไขที่กำหนด

ts
// FP: Count down using recursion
const countDown = (n: number): number[] =>
  n < 0 ? [] : [n, ...countDown(n - 1)];
// Usage: countDown(5) // [5,4,3,2,1,0]

อัลกอริทึมการค้นหา (Searching Algorithms)

Linear Search (ค้นหาเชิงเส้น)

ค้นหาข้อมูลโดยตรวจสอบทีละรายการจากต้นจนจบ

ts
// FP: Linear search (returns index or -1)
const linearSearch = <T>(arr: T[], target: T): number =>
  arr.findIndex(x => x === target);

Binary Search (ค้นหาแบบทวิภาค)

ค้นหาในข้อมูลที่เรียงลำดับแล้ว โดยแบ่งครึ่งและเลือกค้นหาเฉพาะส่วนที่เป็นไปได้

ts
// FP: Binary search (sorted array)
const binarySearch = <T>(arr: T[], target: T, cmp: (a: T, b: T) => number): number => {
  let low = 0, high = arr.length - 1;
  while (low <= high) {
    const mid = Math.floor((low + high) / 2);
    const c = cmp(arr[mid], target);
    if (c === 0) return mid;
    if (c < 0) low = mid + 1;
    else high = mid - 1;
  }
  return -1;
};
// Usage: binarySearch([1,2,3], 2, (a,b)=>a-b)

อัลกอริทึมการเรียงลำดับ (Sorting Algorithms)

Bubble Sort (เรียงฟองสบู่)

เปรียบเทียบข้อมูลทีละคู่ที่อยู่ติดกันและสลับตำแหน่งถ้าจำเป็น

ts
// FP: Bubble sort (pure, returns new array)
const bubbleSort = (arr: number[]): number[] => {
  const a = [...arr];
  for (let i = 0; i < a.length; i++) {
    for (let j = 0; j < a.length - i - 1; j++) {
      if (a[j] > a[j + 1]) {
        [a[j], a[j + 1]] = [a[j + 1], a[j]];
      }
    }
  }
  return a;
};

Selection Sort (เรียงแบบเลือก)

ค้นหาข้อมูลที่น้อยที่สุดในส่วนที่ยังไม่เรียงและนำมาวางในตำแหน่งถัดไป

ts
// FP: Selection sort (pure, returns new array)
const selectionSort = (arr: number[]): number[] => {
  const a = [...arr];
  for (let i = 0; i < a.length - 1; i++) {
    let minIndex = i;
    for (let j = i + 1; j < a.length; j++) {
      if (a[j] < a[minIndex]) minIndex = j;
    }
    if (minIndex !== i) {
      [a[i], a[minIndex]] = [a[minIndex], a[i]];
    }
  }
  return a;
};

Insertion Sort (เรียงแทรก)

แทรกข้อมูลแต่ละตัวลงในตำแหน่งที่เหมาะสมในส่วนที่เรียงแล้ว

ts
// FP: Insertion sort (pure, returns new array)
const insertionSort = (arr: number[]): number[] => {
  return arr.reduce<number[]>((sorted, value) => {
    const idx = sorted.findIndex(x => x > value);
    if (idx === -1) return [...sorted, value];
    return [...sorted.slice(0, idx), value, ...sorted.slice(idx)];
  }, []);
};

Merge Sort (เรียงแบบผสาน)

แบ่งข้อมูลเป็นส่วนย่อย ๆ เรียงลำดับ แล้วนำกลับมารวมกัน

ts
// FP: Merge sort (pure)
const mergeSort = (arr: number[]): number[] => {
  if (arr.length <= 1) return arr;
  const mid = Math.floor(arr.length / 2);
  const left = mergeSort(arr.slice(0, mid));
  const right = mergeSort(arr.slice(mid));
  return merge(left, right);
};

const merge = (left: number[], right: number[]): number[] => {
  if (left.length === 0) return right;
  if (right.length === 0) return left;
  return left[0] < right[0]
    ? [left[0], ...merge(left.slice(1), right)]
    : [right[0], ...merge(left, right.slice(1))];
};

Quick Sort (เรียงแบบเร็ว)

เลือกข้อมูลหนึ่งตัวเป็น pivot แล้วแบ่งข้อมูลเป็นสองกลุ่ม น้อยกว่าและมากกว่า pivot

ts
// FP: Quick sort (pure)
const quickSort = (arr: number[]): number[] => {
  if (arr.length <= 1) return arr;
  const [pivot, ...rest] = arr;
  const left = rest.filter(x => x < pivot);
  const right = rest.filter(x => x >= pivot);
  return [...quickSort(left), pivot, ...quickSort(right)];
};

อัลกอริทึมเชิงโครงสร้างข้อมูล (Data Structure Algorithms)

Stack Operations (การทำงานกับสแตก)

โครงสร้างข้อมูลแบบ LIFO (Last In First Out) ที่มีการเพิ่มและลบข้อมูลจากด้านบนสุด

ts
// FP: Stack using array and pure functions
export type Stack<T> = readonly T[];
export const stackPush = <T>(stack: Stack<T>, item: T): Stack<T> => [...stack, item];
export const stackPop = <T>(stack: Stack<T>): [T | undefined, Stack<T>] =>
  stack.length === 0 ? [undefined, stack] : [stack[stack.length - 1], stack.slice(0, -1)];
export const stackPeek = <T>(stack: Stack<T>): T | undefined => stack[stack.length - 1];
export const stackIsEmpty = <T>(stack: Stack<T>): boolean => stack.length === 0;

Queue Operations (การทำงานกับคิว)

โครงสร้างข้อมูลแบบ FIFO (First In First Out) ที่มีการเพิ่มข้อมูลที่ท้ายและลบจากด้านหน้า

ts
// FP: Queue using array and pure functions
export type Queue<T> = readonly T[];
export const queueEnqueue = <T>(queue: Queue<T>, item: T): Queue<T> => [...queue, item];
export const queueDequeue = <T>(queue: Queue<T>): [T | undefined, Queue<T>] =>
  queue.length === 0 ? [undefined, queue] : [queue[0], queue.slice(1)];
export const queueFront = <T>(queue: Queue<T>): T | undefined => queue[0];
export const queueIsEmpty = <T>(queue: Queue<T>): boolean => queue.length === 0;

Linked List Algorithms (การทำงานกับลิงก์ลิสต์)

โครงสร้างข้อมูลที่แต่ละโหนดเก็บข้อมูลและการอ้างอิงไปยังโหนดถัดไป

ts
// FP: Linked list as algebraic data type
export type ListNode<T> = { value: T; next: ListNode<T> | null };
export type LinkedList<T> = ListNode<T> | null;
export const listAppend = <T>(list: LinkedList<T>, value: T): LinkedList<T> =>
  list === null ? { value, next: null } : { ...list, next: listAppend(list.next, value) };
export const listToArray = <T>(list: LinkedList<T>): T[] => {
  const result: T[] = [];
  let node = list;
  while (node) {
    result.push(node.value);
    node = node.next;
  }
  return result;
};