The first most effective thing was taking a data structures class. It was the second programming class I took in college, and I use the knowledge from that class every day. I think that you can be a pretty good programmer without a lot of the theoretical stuff you get taught in CS classes, but data structures is not one of the things you can skip.
Another very useful thing I did was was read The Little Schemer (http://www.amazon.com/Little-Schemer-Daniel-P-Friedman/dp/02...). Before reading it I'd had a lot of trouble thinking recursively, and since reading it I've had very little trouble. I've also found its question-and-answer style very useful for teaching other people how to program using recursion.