โจทย์: Insert into a Binary Search Tree
ให้ Binary Search Tree (BST) และค่า val ต้องแทรกโหนดใหม่ที่มีค่า val ลงใน BST โดยที่หลังแทรกเสร็จ ต้นไม้ยังคงเป็น BST อยู่ (ค่าด้านซ้ายน้อยกว่าโหนด ค่าด้านขวาเยอะกว่าโหนด)
ตัวอย่าง: BST เดิม: [4,2,7,1,3] แทรก 5 → ผลลัพธ์: [4,2,7,1,3,5]
อัลกอริทึม: Recursive Insertion
- ฟังก์ชัน
insertIntoBST(root, val)แบบ recursive - ถ้า
root == nullptr: สร้างโหนดใหม่ค่าvalส่งคืนเป็น root ใหม่ - ถ้า
root->val > val: แทรกไปซ้าย →root->left = insertIntoBST(root->left, val) - มิฉะนั้น (root->val < val): แทรกไปขวา →
root->right = insertIntoBST(root->right, val) - ส่งคืน
root
สมมติฐาน: BST ไม่มีค่าซ้ำ (no duplicates) หากมีค่าซ้ำ ปกติจะแทรกไปขวา (หรือซ้าย ตามนิยาม)
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
struct TreeNode {
int val;
TreeNode *left, *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (!root) return new TreeNode(val);
if (root->val > val) {
root->left = insertIntoBST(root->left, val);
} else {
root->right = insertIntoBST(root->right, val);
}
return root;
}
};
// Helper: สร้างต้นไม้จาก level-order (สำหรับทดสอบ)
TreeNode* make_tree(vector<int> v) {
if (v.empty()) return nullptr;
TreeNode* root = new TreeNode(v[0]);
queue<TreeNode*> q;
q.push(root);
int i = 1;
while (!q.empty() && i < v.size()) {
TreeNode* curr = q.front(); q.pop();
if (i < v.size() && v[i] != -1) {
curr->left = new TreeNode(v[i]);
q.push(curr->left);
}
i++;
if (i < v.size() && v[i] != -1) {
curr->right = new TreeNode(v[i]);
q.push(curr->right);
}
i++;
}
return root;
}
// Helper: พิมพ์ต้นไม้ level-order
void print_tree(TreeNode* root) {
if (!root) return;
queue<TreeNode*> q;
q.push(root);
cout << "[";
bool first = true;
while (!q.empty()) {
TreeNode* curr = q.front(); q.pop();
if (!first) cout << ",";
first = false;
if (curr) {
cout << curr->val;
q.push(curr->left);
q.push(curr->right);
} else {
cout << "null";
}
}
cout << "]" << endl;
}
int main() {
Solution ob;
vector<int> v = {4, 2, 7, 1, 3};
TreeNode* root = make_tree(v);
cout << "ต้นไม้เดิม: ";
print_tree(root);
TreeNode* new_root = ob.insertIntoBST(root, 5);
cout << "หลังแทรก 5: ";
print_tree(new_root);
return 0;
}
Input
[4,2,7,1,3] 5
Output
[4,2,7,1,3,5]
ความซับซ้อน (Complexity)
- เวลา: O(h) โดย h = ความสูงของต้นไม้ (เฉลี่ย O(log n) สำหรับต้นไม้สมดุล, สูงสุด O(n) สำหรับ skewed tree)
- พื้นที่: O(h) เรียกซ้ำ recursive stack
แก้ไขจากโค้ดต้นฉบับ: โค้ดต้นฉบับมีฟังก์ชัน insert() แบบ level-order (สำหรับ complete binary tree) ไม่ใช่ BST insertion และมีบั๊กหลายจุด ได้เขียนฟังก์ชัน make_tree และ print_tree ใหม่ให้ถูกต้อง