Merge Sort
เรียงครึ่งซ้ายขวาแบบ recursion แล้ว merge
Merge Sort คืออะไร?
เรียงครึ่งซ้ายขวาแบบ recursion แล้ว merge
ใช้ divide-and-conquer รับประกัน O(n log n)
ประเด็นสำคัญ
- ทดสอบ input ว่าง หนึ่งสมาชิก ซ้ำ และเรียงแล้ว
- แยก correctness จาก optimization
- ใช้ standard library ใน production เมื่อเหมาะสม
ภาพจำลอง Merge Sort
O(n)กด เล่น หรือ ทีละขั้น เพื่อดูการเปรียบเทียบและการย้ายข้อมูลแต่ละขั้น
ตัวอย่างโค้ด C และ C++
main.c
#include <stdio.h>
#include <stdlib.h>
void merge_sort(int *values, int *temporary, int left, int right) {
if (right - left < 2) return;
int middle = (left + right) / 2;
merge_sort(values, temporary, left, middle);
merge_sort(values, temporary, middle, right);
int first = left;
int second = middle;
int output = left;
while (first < middle && second < right) {
temporary[output++] = values[first] < values[second]
? values[first++] : values[second++];
}
while (first < middle) temporary[output++] = values[first++];
while (second < right) temporary[output++] = values[second++];
for (int index = left; index < right; ++index) {
values[index] = temporary[index];
}
}
int main(void) {
int values[] = {8, 3, 6, 2, 7};
int temporary[5];
merge_sort(values, temporary, 0, 5);
for (int index = 0; index < 5; ++index) {
printf("%d ", values[index]);
}
}
2 3 6 7 8
C++
main.cpp
#include <algorithm>
#include <iostream>
#include <vector>
void merge_sort(std::vector<int>& values) {
if (values.size() < 2) return;
auto middle = values.begin() + values.size() / 2;
std::vector<int> left(values.begin(), middle);
std::vector<int> right(middle, values.end());
merge_sort(left);
merge_sort(right);
std::merge(left.begin(), left.end(), right.begin(), right.end(),
values.begin());
}
int main() {
std::vector values{8, 3, 6, 2, 7};
merge_sort(values);
for (int value : values) {
std::cout << value << ' ';
}
}
2 3 6 7 8
เปรียบเทียบ C และ C++
ทั้งสองใช้ memory เพิ่ม O(n) C จัดการ buffer เอง ส่วน C++ ใช้ vector และ standard algorithm
C
Loop, pointer, length และ buffer เขียนอย่างชัดเจน
C++
Iterator และ algorithm แยก operation จาก storage
แบบฝึกหัด
รันทั้งสองเวอร์ชันแล้วแก้ไขเพื่อสังเกตความแตกต่างของภาษา
- ไล่ตามทุก comparison
- ทดสอบ duplicate และ extreme value
- Benchmark กับ standard library