ภาพรวม Sorted Array
Sorted Array คืออาร์เรย์ที่ข้อมูลถูกจัดเรียงลำดับ (มักเป็นน้อยไปมาก) อยู่แล้ว ข้อได้เปรียบคือการค้นหาเร็ว (Binary Search O(log n)) แต่การแทรก/ลบช้ากว่า Unsorted Array (O(n)) เพราะต้องเลื่อนข้อมูล
การแทรกข้อมูลใน Sorted Array (Insert)
ขั้นตอน:
- หาตำแหน่งที่ควรแทรก (ใช้ Binary Search)
- เลื่อนข้อมูลจากตำแหน่งนั้นไปขวา 1 ช่อง
- วางค่าใหม่ในตำแหน่งที่ว่าง
- เพิ่ม Size ขึ้น 1
อัลกอริทึม Insert
INSERT_SORTED(arr, n, key):
IF n >= MAX_SIZE: RETURN ERROR
i = n - 1
WHILE i >= 0 AND arr[i] > key:
arr[i + 1] = arr[i]
i = i - 1
arr[i + 1] = key
n = n + 1
การลบข้อมูลจาก Sorted Array (Delete)
ขั้นตอน:
- ค้นหาตำแหน่งของ Key (ใช้ Binary Search)
- ถ้าไม่พบ → Return Error
- เลื่อนข้อมูลจากตำแหน่งถัดไปไปซ้าย 1 ช่อง
- ลด Size ลง 1
อัลกอริทึม Delete
DELETE_SORTED(arr, n, key):
pos = BINARY_SEARCH(arr, 0, n-1, key)
IF pos == -1: RETURN NOT_FOUND
FOR i = pos TO n-2:
arr[i] = arr[i + 1]
n = n - 1
Binary Search Helper
int binarySearch(int arr[], int low, int high, int key) {
if (high < low) return -1;
int mid = low + (high - low) / 2;
if (key == arr[mid]) return mid;
if (key > arr[mid]) return binarySearch(arr, mid + 1, high, key);
return binarySearch(arr, low, mid - 1, key);
}
ตัวอย่างโค้ด C++ สมบูรณ์
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 100;
void display(int arr[], int n) {
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
}
int binarySearch(int arr[], int low, int high, int key) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == key) return mid;
if (arr[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}
bool insertSorted(int arr[], int& n, int key) {
if (n >= MAX) {
cout << "Array is full!\n";
return false;
}
// หาตำแหน่งแทรก (Lower Bound)
int i = n - 1;
while (i >= 0 && arr[i] > key) {
arr[i + 1] = arr[i];
i--;
}
arr[i + 1] = key;
n++;
return true;
}
bool deleteSorted(int arr[], int& n, int key) {
int pos = binarySearch(arr, 0, n - 1, key);
if (pos == -1) {
cout << "Element " << key << " not found.\n";
return false;
}
for (int i = pos; i < n - 1; i++) {
arr[i] = arr[i + 1];
}
n--;
return true;
}
int main() {
int arr[MAX] = {};
int n = 0;
cout << "=== Sorted Array Demo ===\n\n";
// Insert
cout << "Inserting: 10, 20, 30, 40, 50, 60, 70\n";
insertSorted(arr, n, 10);
insertSorted(arr, n, 20);
insertSorted(arr, n, 30);
insertSorted(arr, n, 40);
insertSorted(arr, n, 50);
insertSorted(arr, n, 60);
insertSorted(arr, n, 70);
display(arr, n);
// Delete
cout << "\nDeleting 35 (not exist): ";
deleteSorted(arr, n, 35);
display(arr, n);
cout << "Deleting 40: ";
deleteSorted(arr, n, 40);
display(arr, n);
cout << "Deleting 60: ";
deleteSorted(arr, n, 60);
display(arr, n);
// Insert ใหม่
cout << "\nInserting 35, 55:\n";
insertSorted(arr, n, 35);
insertSorted(arr, n, 55);
display(arr, n);
return 0;
}
ผลลัพธ์ตัวอย่าง
=== Sorted Array Demo === Inserting: 10, 20, 30, 40, 50, 60, 70 10 20 30 40 50 60 70 Deleting 35 (not exist): Element 35 not found. 10 20 30 40 50 60 70 Deleting 40: 10 20 30 50 60 70 Deleting 60: 10 20 30 50 70 Inserting 35, 55: 10 20 30 35 50 55 70
การใช้ STL แทนการเขียนเอง
ใน C++ จริง ควรใช้ std::vector + std::lower_bound + insert/erase:
#include <vector> #include <algorithm> vectorsortedVec; void insertSorted(vector & v, int key) { auto it = lower_bound(v.begin(), v.end(), key); v.insert(it, key); // O(n) shift } void deleteSorted(vector & v, int key) { auto it = lower_bound(v.begin(), v.end(), key); if (it != v.end() && *it == key) { v.erase(it); // O(n) shift } }
เปรียบเทียบโครงสร้างข้อมูลสำหรับข้อมูลเรียงลำดับ
| Data Structure | Search | Insert | Delete | Memory |
|---|---|---|---|---|
| Sorted Array | O(log n) | O(n) | O(n) | Compact |
| Binary Search Tree | O(log n)* | O(log n)* | O(log n)* | Pointers |
| AVL/Red-Black Tree | O(log n) | O(log n) | O(log n) | Pointers |
| Skip List | O(log n) | O(log n) | O(log n) | Pointers |
| std::set/map | O(log n) | O(log n) | O(log n) | Pointers |
| std::vector + sort | O(log n) | O(1) amortized** | O(n) | Compact |
* Average case, ** ถ้าเพิ่มท้ายแล้ว Sort ครั้งเดียว
เมื่อไหร่ควรใช้ Sorted Array?
- ข้อมูลไม่เปลี่ยนแปลงบ่อย (Read-heavy, Write-rare)
- ต้องการ Memory Efficiency (ไม่มี Pointer Overhead)
- Cache Friendly (Contiguous Memory)
- ข้อมูลขนาดเล็ก-ปานกลาง (n < 10,000)
- ต้องการ Random Access ด้วย Index
ข้อควรระวัง
- Insert/Delete ที่กลางอาร์เรย์ ต้อง Shift ข้อมูล O(n)
- Fixed Size Array ต้องจัดการ Capacity เอง
- Duplicate Values: Binary Search หาตำแหน่งไหนก็ได้ของค่าที่ซ้ำ
- ใช้
std::lower_bound/upper_boundสำหรับ Range Query