Hi,
maybe "The Standard Evaluation Procedure" reference is helpful for you. Wolfram usually starts from the head of the function to read attributes. Afterwards the default evaluation process starts from the innermost subexpression(leaves). But here you dont have an evaluation but a rule .You could write it as
rules = ReplaceAll[rules, (c -> tt) -> (c -> ff)]
and it just replaces the part "c->tt" by "c->ff" and gives the final result. If you would try
rules = ReplaceAll[rules, c -> ff]
just the "c" would be replaced by "ff" and you would obtain
{a -> tt, b -> ff, ff -> tt, d -> ff}
The question regarding your TreeForm might be answered by the example
ReplaceAll[Sin[Pi],Pi->a]
which gives just 0 as an output, since here the Trace[] is, that first Sin[Pi] is evaluated and thus the Pi vanished and cant be replaced anymore. If you want to have a different sequence of evaluations than innermost subexpression you might use Attributes like HoldAll , to change the behaviour to "Non?Standard Evaluation",