typedef se usa para apodar un tipo y después crear cosas de ese tipo con el apodo. Pueden ser clases o tipos primitivos.
Mejor vea este ejemplo:
http://es.wikipedia.org/wiki/Typedef
typename es un poco más truculento. Tiene dos usos.
1. En el uso de plantillas (que oficialmente no hemos visto) significa que la Lista (el Arbol, el Grafo, la Pila) puede ser de cualquier tipo.
2. "Si uno no tiene definido un tipo"(*) uno puede declararlo de un tipo genérico "typename" y el programa compilaría. Es medio extraño pero en realidad este era el uso inicial que tenía y se ajustó bastante bien para las plantillas, el uso más común actualmente.
"Si uno no tiene definido un tipo"(*): esto es:
1. eventualmente voy a hacer un Loro...
2. pero todavía no lo tengo
3. pero sé que lo voy a tener y
4. además quiero saber lo que ya programé compila
5. a pesar de que el Loro no exista...
Si no entiende la segunda razón, pregunteme en clase... la que más nos interesa es la primera
Roberto