Notes & software courses · Free to learn
Aph's Blog
On this page

Sorting เชิงลึก

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

เข้าใจ algorithm การเรียงลำดับ ไม่ใช่แค่เรียก .sort() — merge/quick sort และการเลือกใช้

การเรียงลำดับเป็นพื้นฐานของอัลกอริทึมมากมาย งานจริงใช้ sorted() ก็พอ แต่การเข้าใจว่ามันทำงานยังไงข้างใต้ ช่วยให้คิดวิเคราะห์เป็นและตอบโจทย์สัมภาษณ์ได้

algorithm ช้า ๆ ที่เข้าใจง่าย (O(n²))

bubble/selection/insertion sort เข้าใจง่ายแต่ช้า — ดีสำหรับเรียนรู้แนวคิด

python
# bubble sort: สลับคู่ที่อยู่ผิดที่ ไล่ไปเรื่อย ๆ
def bubble_sort(arr):
    arr = arr[:]
    n = len(arr)
    for i in range(n):
        for j in range(n - 1 - i):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

print(bubble_sort([5, 2, 8, 1]))   # [1, 2, 5, 8]

Merge Sort — O(n log n)

แบ่งครึ่งไปเรื่อย ๆ จนเหลือตัวเดียว แล้วรวม (merge) กลับแบบเรียง — ตัวอย่างคลาสสิกของ divide and conquer

python
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])    # เรียงครึ่งซ้าย
    right = merge_sort(arr[mid:])   # เรียงครึ่งขวา
    return merge(left, right)       # รวมแบบเรียง

def merge(a, b):
    result, i, j = [], 0, 0
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            result.append(a[i]); i += 1
        else:
            result.append(b[j]); j += 1
    result.extend(a[i:]); result.extend(b[j:])
    return result

print(merge_sort([5, 2, 8, 1, 9, 3]))   # [1,2,3,5,8,9]

เลือกใช้ & stability

algorithmBig-Oหมายเหตุ
bubble/selectionO(n²)เรียนรู้ ไม่ใช้จริง
merge sortO(n log n)เสถียร (stable)
quick sortO(n log n) เฉลี่ยเร็วจริง แต่แย่สุด O(n²)
Python sorted()O(n log n)Timsort — ใช้จริง
งานจริงใช้ sorted() (Timsort)

Python มี Timsort ที่เร็วและเสถียรอยู่แล้ว — งานจริงใช้ sorted()/list.sort() พร้อม key= (จากบท 1) ไม่ต้องเขียนเอง แต่เข้าใจ merge/quick sort ไว้สำหรับวิเคราะห์และสัมภาษณ์ stable = ตัวที่ค่าเท่ากันคงลำดับเดิม สำคัญตอนเรียงหลายเงื่อนไข

สรุปหัวข้อนี้

  • bubble/selection/insertion: O(n²) เข้าใจง่ายแต่ช้า
  • merge sort: แบ่งครึ่ง+รวม O(n log n) เสถียร (divide & conquer)
  • quick sort: เร็วเฉลี่ย O(n log n) แต่แย่สุด O(n²)
  • งานจริงใช้ sorted() (Timsort); stable = คงลำดับค่าที่เท่ากัน
แบบฝึกหัด

1) เขียน merge sort เอง 2) เทียบเวลากับ sorted() ด้วย timeit (บท 3) 3) เรียง list of dict หลายเงื่อนไขด้วย sorted(key=) 4) อธิบายว่า stable sort สำคัญตอนไหน