Nút cuối không tự biết nút trước
Đếm nút bắt đầu ở `head`, tăng một mỗi khi đi qua nút, dừng ở `None`. Để xóa nút cuối của danh sách có từ **hai nút**, phải dừng tại nút **ngay trước nút cuối** rồi đặt `next` của nó thành `None`. Nếu chỉ có **một nút**, đặt `L.head = None`; chỉ gán `head.next = None` thì nút ấy vẫn là đầu danh sách, chưa bị xóa. Với danh sách rỗng, không có gì để xóa.
Hai hàm dùng lại Node và LL
```python
def dem_nut(L):
so_nut = 0
x = L.head
while x is not None:
so_nut += 1
x = x.next
return so_nut
def xoa_cuoi(L):
if L.head is None:
return False
if L.head.next is None:
L.head = None
return True
truoc = L.head
while truoc.next.next is not None:
truoc = truoc.next
truoc.next = None
return True
L = LL()
for k in [8, 2, 5]:
chen_dau(L, k)
print(dem_nut(L), cac_khoa(L))
xoa_cuoi(L)
print(dem_nut(L), cac_khoa(L))
```
Đoạn mã dùng `Node`, `LL`, `chen_dau` và `cac_khoa` ở bài trước. Sau ba lần chèn, kết quả là `3 [5, 2, 8]`; xóa cuối được `2 [5, 2]`. Vòng `while` chỉ chạy khi đã có ít nhất hai nút, nên `truoc.next` chắc chắn là một nút trước khi đọc tiếp `.next`. Hàm trả `False` khi danh sách rỗng để phân biệt không xóa được với đã xóa.
Bài luyện
Danh sách rỗng có bao nhiêu nút?
Vòng duyệt không chạy khi head là None.
Không có nút đầu.
Không có hai nút.
Hàm trả được 0.
Lời giải
head là None ngay từ đầu nên dem_nut không tăng so_nut và trả 0.
Bài luyện
Với danh sách chỉ có `head → 5 → None`, xóa nút cuối phải làm gì?
Sau đó không còn nút nào từ head.
next vốn đã None, head vẫn trỏ vào 5.
Đổi dữ liệu không bỏ nút.
Có thể xóa bằng cách đổi head.
Lời giải
Nút duy nhất vừa là đầu vừa là cuối; bỏ nó bằng cách cho head thành None.
Bài luyện
Với `head → 5 → 2 → 8 → None`, sau khi xóa cuối, nút nào có next bằng None?
5 vẫn trỏ tới 2.
2 trở thành nút cuối mới.
8 đã bị bỏ khỏi chuỗi.
Danh sách vẫn còn hai nút.
Lời giải
Xóa nút 8 bằng cách đặt next của nút đứng trước là 2 thành None; 2 là nút cuối mới.
Đang học