Aquí hay una manera de hacerlo sin aplanar el árbol.
De la definición, aquí,
data BinaryTree a = Null | Node (BinaryTree a) a (BinaryTree a)
deriving Show
Uno puede ver que atravesar el árbol de izquierda a derecha, ignorando Node
y entre paréntesis, le da una secuencia alterna de Null
sy a
s. Es decir, entre cada dos valores, hay un Null
.
Mi plan es verificar que cada subárbol satisfaga los requisitos adecuados : podemos refinar los requisitos en cada uno Node
, recordando qué valores estamos entre ellos, y luego probarlos en cada uno Null
. Como hay un Null
par de valores entre cada orden, habremos probado que todos los pares en orden (de izquierda a derecha) no disminuyen.
¿Qué es un requisito? Es un límite inferior y superior suelto en los valores del árbol. Para expresar los requisitos, incluidos los que se encuentran en los extremos más a la izquierda y a la derecha, podemos extender cualquier pedido con Bot
tom y Top
elementos, de la siguiente manera:
data TopBot a = Bot | Val a | Top deriving (Show, Eq, Ord)
Ahora, verifiquemos que un árbol determinado cumpla con los requisitos de estar en orden y entre límites dados.
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
Un árbol de búsqueda binaria es un árbol que está en orden y entre Bot
y Top
.
isBSTree :: Ord a => BinaryTree a -> Bool
isBSTree = ordBetween Bot Top
El cálculo de los actuales valores extremales en cada sub-árbol, burbujeando ellos hacia el exterior, le da más información que usted necesita, y es más incómoda en los casos extremos donde un subárbol izquierdo o derecho está vacío. Mantener y verificar los requisitos , empujándolos hacia adentro, es bastante más uniforme.
flattenTree
primero. Puede regresarFalse
temprano si un nodo viola la propiedad de búsqueda sin tener que atravesar todo el subárbol enraizado en ese nodo.