What is the difference between Strategy pattern and Visitor Pattern?

The strategy pattern is like a 1:many relationship. When there is one type of object and I want to apply multiple operations to it, I use the strategy pattern. For example, if I have a Video class that encapsulates a video clip, I might want to compress it in different ways. So I create a bunch of strategy classes:

MpegCompression
AviCompression
QuickTimeCompression

and so on.

I think of the visitor pattern as a many:many relationship. Let's say my application grows to to include not just video, but audio clips as well. If I stick with the strategy pattern, I have to duplicate my compression classes-- one for video and one for audio:

MpegVideoCompression
MpegAudioCompression

and so on...

If I switch to the visitor pattern, I do not have to duplicate the strategy classes. I achieve my goal by adding methods:

MpegCompressionVisitor::compressVideo(Video object)    
MpegCompressionVisitor::compressAudio(Audio object)

[UPDATE: with Java] I used the visitor pattern in a Java app. It came out a little different than described above. Here is a Java version for this example.

// Visitor interface
interface Compressor {

  // Visitor methods
  void compress(Video object);
  void compress(Audio object);
}

// Visitor implementation
class MpegCompressor implements Compressor {
  
  public void compress(Video object) {
    // ...
  }

  public void compress(Audio object) {
    // ...
  }
}

And now the interface and class to be visited:

interface Compressible {

  void accept(Compressor compressor);
}

class Video implements Compressible {

  // If the Compressor is an instance of MpegCompressionVisitor,
  // the system prints "Mpeg video compression"
  void accept(Compressor compressor) {
    compressor.compress(this);
}

A Strategy pattern is used to expose various algorithms to a standardized interface. A typical example could be a sort utility that would let the user (programmer) choose between various sort algorithms each called via the same interface.

A Visitor pattern lives at a different level. It details a mechanism with which objects can accept a reference to another object (the visitor) which exposes a predetermined interface that the target object can call upon itself. Of course, different visitors would present the same interface but have different implementations.

Coming back to our example, a collection of sort algorithms could be implemented either via the Strategy pattern or via the Visitor pattern.

With the Strategy method, each algorithm presents the same interface and takes arrays of target objects as parameters for example. With the Visitor pattern, it would be the target array that takes the "visiting" algorithm as a parameter. In this case, the target would "accept()" the selected visitor and call its "visit()" method upon invocation of the target's sort method in our example.

Two sides of the same coin...

Does this make sense?