Ba trường và một khóa duy nhất
Mỗi nút lưu `[tên liên hệ, tên đầy đủ, số điện thoại]`. Tên liên hệ là khóa duy nhất của mô hình; số điện thoại là chuỗi để không mất chữ số 0 đầu nếu có.
Bộ mẫu dùng năm liên hệ giả định theo thứ tự Minh, Bao, Vy, An, Khanh. Tên đầy đủ có dạng “Liên hệ mẫu Minh”; trường số điện thoại dùng nhãn SO_MAU_01,…, không phải số để gọi. Tệp contacts.inp có ba trường cách bằng dấu phẩy.
Dùng lại record_search và record_upsert. Cả thao tác chèn lẫn tìm phải so cùng trường T[k][0] và cùng quy tắc chuỗi. Không so tên đầy đủ khi chèn rồi lại so tên liên hệ khi tìm.
Nạp tệp và giữ đúng kiểu dữ liệu
Hai hàm trong bst.py nạp các tệp mẫu. csv.reader trả các trường dạng chuỗi, vì vậy giá được chuyển bằng int còn số điện thoại giữ nguyên chuỗi. Tệp phải đủ hai trường với thực đơn, ba trường với danh bạ; dòng trống được bỏ qua.
```python
def load_menu(path):
import csv
T = Tree()
with open(path, encoding='utf-8', newline='') as f:
for row in csv.reader(f):
if not row:
continue
name, raw_price = [x.strip() for x in row]
price = int(raw_price)
if not name or price <= 0:
raise ValueError("Tên hoặc giá không hợp lệ")
record_upsert(T, [name, price])
return T
def load_contacts(path):
import csv
T = Tree()
with open(path, encoding='utf-8', newline='') as f:
for row in csv.reader(f):
if not row:
continue
key, full_name, phone = [x.strip() for x in row]
if not key or not full_name or not phone:
raise ValueError("Thiếu trường liên hệ")
record_upsert(T, [key, full_name, phone])
return T
```
Duyệt giữa trước khi in
Chạy danh_ba.py, chọn 1: tên liên hệ xuất hiện theo thứ tự **An, Bao, Khanh, Minh, Vy**. Chọn 2, nhập `Bao` để nhận ba trường của Bao; nhập tên không có để thấy thông báo không tìm thấy.
Chọn 3, nhập `Bao`, tên đầy đủ mẫu mới và nhãn số `SO_MAU_MOI`; tra lại phải có thông tin mới và danh sách vẫn chỉ một Bao. Thử thêm `Chi` với thông tin mẫu, sau đó in lại: Chi nằm giữa Bao và Khanh. Nhập 0 để thoát.
Để in, chương trình tạo rows=[], gọi `record_inorder(T,0,rows)` rồi in mỗi hàng. Duyệt theo thứ tự khóa cần dùng, không in list T trực tiếp vì list ấy ghi vị trí cấu trúc và có thể chứa None. Bộ mẫu phân biệt hoa/thường, dùng so sánh Unicode của Python; các cập nhật chỉ nằm trong lần chạy hiện tại.
Bài luyện
Trường số điện thoại nên giữ dạng chuỗi vì lý do nào?
Kiểu chuỗi không tự tạo chức năng gọi.
Khóa của cây đang là tên liên hệ.
Chuỗi không tự chuyển thành số.
Đúng. Đây là thông tin nhận diện, không cần tính số học.
Lời giải
Chuyển chuỗi như 0012 thành số nguyên sẽ mất các số 0 đầu. Lưu chuỗi giữ nguyên cách biểu diễn; trong bộ mẫu còn có nhãn SO_MAU_01 không phải số.
Bài luyện
Duyệt giữa danh bạ có khóa Minh, Bao, Vy, An, Khanh theo so sánh Python cho thứ tự nào?
Đây là thứ tự nạp đầu vào.
Đúng. Duyệt giữa BST cho khóa tăng dần.
Đây là thứ tự giảm dần.
An nhỏ hơn Bao nên phải đứng trước.
Lời giải
Theo thứ tự chuỗi của các khóa mẫu, An<Bao<Khanh<Minh<Vy. record_inorder thăm trái–gốc–phải nên cho đúng thứ tự đó, khác thứ tự ghi trong tệp.
Bài luyện
Tại sao không in list T trực tiếp để thay kết quả duyệt giữa?
Sau nạp, T có dữ liệu.
Dữ liệu mẫu không bị mã hóa.
Đúng. Cần duyệt cây để tạo thứ tự khóa.
Python in được list nhưng thứ tự ấy không đúng yêu cầu.
Lời giải
Phần tử T[0] là gốc, các vị trí tiếp theo gắn với các con theo công thức, còn có thể có None. Thứ tự này không phải thứ tự khóa tăng dần. Duyệt giữa mới thu danh sách cần in.
Đang học