2.1. Khái niệm cây nhị phân
2.2. Một số tính chất của cây nhị phân
- Các đặc điểm nêu ở mục 1.2 cũng đúng với cây nhị phân
Là một dạng quan trọng của cấu trúc cây.
Đặc điểm là mọi nút trên cây chỉ có tối đa là hai con.
Đối với cây con của một nút người ta cũng phân biệt cây con trái và cây con phải.
Hình 6.3: Cây nhị phân
A
B C
D E F G
112
- Số lượng tối đa các nút ở mức i trên một cây nhị phân là 2(i-1). (i>=1) - Số lượng tối đa các nút trên một cây nhị phân có chiều cao h là: 2h – 1 (h>=1)
- Một số dạng đặc biệt của cây nhị phân
o Cây nhị phân hoàn chỉnh: Các nút ứng với các mức trừ mức cuối cùng đạt tối đa (e, f là cây nhị phân hoàn chỉnh).
o Cây nhị phân hoàn chỉnh có chiều cao nhỏ nhất.
o Cây nhị phân suy biến (a, b, c, d) có chiều cao lớn nhất. 2.3. Biểu diễn cây nhị phân.
2.3.1. Lưu trữ cây bằng véc tơ kế tiếp (lưu trữ kế tiếp):
Dùng một véctơ lưu trữ V gồm MaxSize phần tử nhớ kế tiếp để lưu trữ các nút trên cây.
a. Nguyên tắc lưu trữ
- Cha có số thứ tự là i thì con có số thứ tự là 2i và 2i+1
Cây lệch phải
Hình 6.4: Cây nhị phân đặc biệt
Cây lệch trái
Cây zic zắc
f) Cây nhị phân đầy đủ Cây nhị phân hoàn chỉnh
113
- Con có số thứ tự là j thì cha có số thứ tự là j/2 (lấy số nguyên dưới) - Quan hệ cha con được xác định qua số thứ tự này.
- Dùng véc tơ V để lưu trữ các nút trên cây theo nguyên tắc nút thứ i của cây được lưu trữ bởi véc tơ V[i].
Nút 0 được lưu trữ bởi phần tử V0, nút 1 được lưu trữ bởi phần tử V1 …
Xét một cây nhị phân hoàn chỉnh không đầy đủ
Véc tơ lưu trữ tương ứng:
Xét một cây nhị phân hoàn chỉnh đầy đủ: Đánh số thứ tự cho các nút trên cây theo trình tự lần lượt từ mức 1 trở lên, hết mức này đến mức khác và trong mỗi mức thì từ trái sang phải
ABCDEFG-0123456
Hình 6.8: Cây nhị phân hoàn chỉnh không đầy đủ Hình 6.7: Lưu trữ kế tiếp với cây nhị phân đầy đủ
Hình 6.6: Cây nhị đầy đủ
114
Nhận xét:
- Ưu điểm:
• Với cách lưu trữ này quan hệ cha con hoàn toàn được xác định thông qua chỉ số của véc tơ lưu trữ.
• Với cây nhị phân đầy đủ thì cách lưu trữ này khá thuận lợi • Truy nhập trực tiếp vào nút của cây thông qua chỉ số phần tử - Nhược điểm:
• Với cây nhị phân không đầy đủ và nhất là các cây nhị phân suy biến thì gây ra lãng phí bộ nhớ vì xuất hiện rất nhiều nút rỗng.
• Nếu cây luôn biến động (thường xuyên có phép bổ sung, loại bỏ tác động thì cách lưu trữ này càng thể hiện nhiều nhược điểm).
Như vậy, thường chỉ dùng cách lưu trữ kế tiếp đối với cây nhị phân đầy đủ hoặc hoàn chỉnh.
b. Khai báo cấu trúc.
Để cài đặt cây nhị phân tổng quát bằng véc tơ lưu trữ kế tiếp, ta dùng một mảng các nút có độ dài tối đa là MaxSize phần tử. Mỗi nút của cây được biểu diễn bằng một bản ghi gồm 3 trường. Trường thứ nhất info kiểu Item (Item có thể là các kiểu dữ liệu đơn giản hoặc kiểu dữ liệu có cấu trúc), trường thứ hai, thứ ba là Lchild và Rchild chứa chỉ số của nút con trái và nút con phải.
Khai báo cấu trúc của danh sách bằng mảng: const int MaxSize=100
typedef struct node { Item info;
int Lchild, Rchild; };
node tree[MaxSize];
2.3.2. Lưu trữ cây bằng danh sách liên kết:
Để khắc phục nhược điểm của lưu trữ kế tiếp, người ta thường dùng danh sách liên kết để lưu trữ với cây nhị phân.
a. Nguyên tắc lưu trữ
- Chỉ lưu trữ những nút tồn tại trên cây
- Với cách lưu trữ móc nối sẽ khắc phục được nhược điểm nêu trên và vừa phản ánh được dáng tự nhiên của cây.
- Dùng một con trỏ T luôn trỏ vào nút gốc của cây để giúp ta truy nhập vào cây. Khi cây rỗng T=NULL
115
o Trường info: Lưu trữ các thông tin tương ứng trên cây
o Trường Lchild: Trỏ tới cây con trái tương ứng của nút
o Trường Rchild: Trỏ tới cây con phải tương ứng của nút Giả thiết ta có một cây nhị phân hoàn chỉnh như hình 6.8 Hình ảnh lưu trữ móc nối
Nhận xét:
- Ưu điểm: Đỡ tốn bộ nhớ
- Nhược điểm: Truy nhập tuần tự bắt đầu từ nút cha tới các nút con b. Khai báo cấu trúc
Cài đặt cây nhị phân tổng quát bằng danh sách liên kết, mỗi nút của cây được biểu diễn bằng một bản ghi gồm 3 trường. Trường thứ nhất info kiểu ElementType (ElementType có thể là các kiểu dữ liệu đơn giản hoặc kiểu dữ liệu có cấu trúc), trường thứ hai, thứ ba là Lchild và Rchild có kiểu dữ liệu con trỏ node chứa địa chỉ của nút con trái và nút con phải.
Đặc biệt cần có thêm con trỏ T để luôn chứa địa chỉ nút gốc của cây. T bằng NULL khi cây rỗng.
Khai báo cấu trúc của cây bằng danh sách liên kết:
Hình 6.10: Lưu trữ một nút trên cây nhị phân
116 struct node { ElementType info; node *Lchild; node *Rchild; };
typedef struct node* TreeNode; TreeNode T;