OK, firstly polymorphism has nothing to do with code-reuse. That's where you're confusing class inheritance with polymorphism (although you're right, polymorphism does depend on inheritance).
No, that's wrong. Value based dispatch depends on inheritance, polymorphism does not. Polymorphism does have something to do with code reuse preciesly because you can write a function that works on values of multiple types.
Here's a polymorhic method that doesn't depend on inheritance in the least:
static T pickFirst<T>(T a, T b)
Normally this isn't very useful, you'd have to constrain the template parameter somehow (and obviously you'd do that using interfaces, and you might almost be able to claim that interfaces depend on inheritance,
but that would also be wrong - consider something like Haskell that has no inheritance but manages to have a type hierarchy and polymorphism anyway; by simply using type-based dispatch rather than value-based dispatch). Consider something like
This is a much more useful function that does not depend on inheritance either, and would still be exceedingly polymorphic in that it can work on lists of any element type (in this case an immutable singly linked list).
So yeah, inheritance is one way of doing subtyping, but not the only way of doing polymorphism.