Đây là một cách để làm điều đó mà không làm phẳng cây.
Từ định nghĩa, ở đây,
data BinaryTree a = Null | Node (BinaryTree a) a (BinaryTree a)
deriving Show
người ta có thể thấy rằng đi qua cây từ trái sang phải, bỏ qua Node
và dấu ngoặc đơn, cung cấp cho bạn một chuỗi xen kẽ của Null
s và a
s. Đó là, giữa mỗi hai giá trị, có một Null
.
Kế hoạch của tôi là kiểm tra xem mỗi cây con có thỏa mãn các yêu cầu phù hợp hay không : chúng ta có thể tinh chỉnh các yêu cầu ở mỗi loại Node
, ghi nhớ những giá trị nào chúng ta nằm giữa, sau đó kiểm tra từng giá trị Null
. Vì có một Null
cặp giá trị theo thứ tự, chúng tôi sẽ kiểm tra xem tất cả các cặp theo thứ tự (từ trái sang phải) không giảm.
Yêu cầu là gì? Đó là một giới hạn dưới và trên lỏng lẻo trên các giá trị trong cây. Để thể hiện các yêu cầu, bao gồm cả các yêu cầu ở cuối cùng bên trái và bên phải, chúng tôi có thể mở rộng bất kỳ thứ tự nào với Bot
tom và Top
các phần tử, như sau:
data TopBot a = Bot | Val a | Top deriving (Show, Eq, Ord)
Bây giờ chúng ta hãy kiểm tra xem một cây nhất định có thỏa mãn các yêu cầu về cả thứ tự và giữa các giới hạn nhất định không.
ordBetween :: Ord a => TopBot a -> TopBot a -> BinaryTree a -> Bool
-- tighten the demanded bounds, left and right of any Node
ordBetween lo hi (Node l x r) = ordBetween lo (Val x) l && ordBetween (Val x) hi r
-- check that the demanded bounds are in order when we reach Null
ordBetween lo hi Null = lo <= hi
Cây tìm kiếm nhị phân là một cây theo thứ tự và giữa Bot
và Top
.
isBSTree :: Ord a => BinaryTree a -> Bool
isBSTree = ordBetween Bot Top
Tính toán các giá trị cực trị thực tế trong mỗi cây con, đưa chúng ra bên ngoài, cung cấp cho bạn nhiều thông tin hơn bạn cần và rất khó sử dụng trong các trường hợp cạnh trong đó cây con trái hoặc phải trống. Duy trì và kiểm tra các yêu cầu , đẩy chúng vào trong, khá đồng đều.
flattenTree
đầu tiên. Bạn có thể quay lạiFalse
sớm nếu một nút vi phạm thuộc tính tìm kiếm mà không phải duyệt toàn bộ cây con gốc ở nút đó.