Trang 1 chứa vị trí 0 đến 19
Đây là phần vận dụng sau hai bài thực hành. Trước hết dùng record_inorder để thu rows đã sắp theo khóa. Với tối đa 20 liên hệ mỗi trang, trang p bắt đầu ở chỉ số (p−1)×20; lấy lát cắt tới start+20, không lấy đầu mút ấy.
Nếu có 21 liên hệ, trang 1 có 20 mục, trang 2 có 1 mục. Tổng trang là `(len(rows)+19)//20`; danh sách rỗng không có trang hợp lệ.
```python
def page_rows(rows, page):
total_pages = (len(rows) + 19)//20
if not isinstance(page, int) or not 1 <= page <= total_pages:
raise ValueError("Trang không hợp lệ")
start = (page-1)*20
return rows[start:start+20]
```
Muốn sắp theo giá phải đổi khóa so sánh
Cây thực đơn ở bài trước dùng tên làm khóa nên duyệt giữa chỉ sắp theo tên. Muốn sắp theo giá, lập một cây riêng với mỗi nút `[giá, tên]`. So giá bằng số nguyên; giá bằng nhau đi sang phải theo biến thể giữ trùng, không cập nhật đè mất món trước.
Sau khi thêm từng món theo thứ tự tệp, gọi record_inorder để thu các hàng [giá,tên]. Các món cùng giá giữ thứ tự xuất hiện trong tệp vì món bằng giá được chèn vào nhánh phải của món đã có.
```python
def price_insert(T, name, price):
k = 0
while k < len(T) and T[k] is not None:
k = left(k) if price < T[k][0] else right(k)
if k >= len(T):
T.extend([None] * (k-len(T)+1))
T[k] = [price, name]
```
Dữ liệu mẫu cho kết quả: Trà gừng 12000, Nước lọc 12000, Cơm nấm 20000, Mì rau 25000. Không so chuỗi “12000” với chuỗi “9000” để sắp theo giá; cần dùng số.
Bộ mẫu và cách chạy
Giải nén toàn bộ ZIP vào một thư mục. Bộ gồm bst.py, demo.py, menu.py, danh_ba.py, menu.inp, contacts.inp và HUONG_DAN.txt. Cần Python 3, không cần cài thư viện ngoài. Mở demo.py trong IDLE rồi Run Module để xem duyệt cây, chèn/tìm, sắp xếp và chiều cao; mở menu.py hoặc danh_ba.py để thực hành bảng chọn.
Trong demo, chèn 5 rồi tìm phải cho chỉ số 9; tìm 11 cho −1; sắp [8,4,8,2] cho [2,4,8,8]; chiều cao sau chèn là 3, min=2, max=14. Nếu không đúng, kiểm dùng insert hay insert_repeat và có tạo danh sách kết quả mới trước mỗi lần duyệt không.
Thực hành trên bản sao với ít khóa. Giữ bst.py cùng thư mục các chương trình; nhập tên đúng dấu và hoa/thường. Mã chỉ dùng dữ liệu giả định, không gửi liên hệ hay thực hiện cuộc gọi; thay đổi trong bảng chọn chưa lưu về tệp. Câu luyện kiểm hiểu cách làm và kết quả; chọn đáp án không thay cho tự chạy mã.
Bài luyện
rows có 21 mục, mỗi trang tối đa 20. Trang 2 lấy lát cắt nào?
Đúng. Chỉ còn mục chỉ số 20 nên nhận một mục.
Bắt đầu 19 sẽ lặp mục cuối trang 1.
Bắt đầu 21 bỏ mất mục còn lại.
Đây là trang 1.
Lời giải
Trang 2 bắt đầu ở (2−1)×20=20, kết thúc trước 40. List chỉ dài 21 nên rows[20:40] chứa đúng phần tử ở chỉ số 20; không cần bổ sung phần tử trống.
Bài luyện
Muốn in thực đơn theo giá tăng dần bằng BST, cần làm gì?
Duyệt giữa sắp theo khóa tên, không tự sắp theo giá.
Đúng. Khóa so sánh phải phù hợp yêu cầu.
Tên món và giá là hai trường khác nhau.
Cần giữ cả các món cùng giá.
Lời giải
BST tổ chức các nút theo khóa so sánh. Để duyệt giữa cho giá tăng, cây phải được dựng theo giá số. Giá có thể trùng nên dùng nhánh phải cho trường hợp bằng, giữ đủ các món.
Bài luyện
Trà gừng rồi Nước lọc cùng giá 12000 được chèn bằng price_insert. Duyệt giữa sẽ hiển thị thế nào?
Hàm không bỏ khóa trùng.
Hàm không cập nhật đè khi bằng giá.
Cây này so giá, không sắp tên khi giá bằng.
Đúng. Giá bằng nhau đi phải, giữ thứ tự xuất hiện.
Lời giải
price_insert đưa món bằng giá sang nhánh phải của món đã có. Khi duyệt giữa, món trước được thăm trước các món cùng giá được thêm sau trong nhánh phải, nên giữ cả hai theo thứ tự đầu vào.
Đang học