ENH/FIX Change Tree underlying data structure

Memory is managed by numpy and the Python garbage collector where it previously could segfaults (#2726).

Typed memoryviews increase readability while maintaining efficiency.

A struct array for tree nodes and values array (size indeterminate at compile time) are the only underlying structure, so each node is locally grouped memory, and joblib dumps will save only two numpy files per tree.