J. M. has shown you a workaround using ArrayRules and as others mentioned, using Conjugate is more prudent. However, to answer your primary question — "Why doesn't ReplaceAll work on SparseArray?", it is because SparseArray is atomic.
In other words, SparseArray objects are "indivisible" and the data contained in them can only be accessed in specific ways (e.g., using undocumented arguments to SparseArray) and not by manipulating its FullForm. You can verify that it is indeed atomic, whereas a regular matrix is not:
AtomQ@m
(* True *)
AtomQ@Normal@m
(* False *)
A similar situation arises with Graph objects, which are also atomic. For instance, the following will not work:
Graph[{1 -> 2, 2 -> 3, 2 -> 4}] /. DirectedEdge -> UndirectedEdge
even though // FullForm will show the presence of DirectedEdge in the structure. Hence it is important for you to know which objects are atomic before you try (unsuccessfully) to use replacement rules on them.
To the best of my knowledge, the list of atomic objects (not including undocumented ones) are those with the following heads:
{Symbol, String, Integer, Real, Rational, Complex, SparseArray, BooleanFunction, Graph}
I(and thenConjugate[])? – J. M.♦ Oct 28 '12 at 13:37conjugate[]function? You can pack there sparse array conversion and use Your transformation rule. – mmal Oct 28 '12 at 13:37