Dynamic array container
My first comment is its named badly.

dynamic_array implies that I can use [] operator on it and get a value out.

You have owned RAW pointers in your structure.

private:
  T* array;
  T* scratch;


First this means you need to look up RAII to make sure these members are correctly deleted.

Second you you need to look up the rule of three (or 5 in C++11) to make sure they are copied correctly.

You have owned RAW pointers in your structure. This means you need to correctly manage the object as a resource. This means constructions/destruction/copy (creation and assignment) need to be taken care of correctly.

Either do this manually or use a standard container that will do it for you. I suggest a standard container.

void print_array()
  {
  for (int i = 0; i &lt; size; i++) cout &lt;&lt; array[i] &lt;&lt; endl;
  }


If you are going to write print_array at least write it so that it can use alternative stream (not just std::cout). Then write the output operator.

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; stream, dynamic_array const&amp; data)
{
     data.print_array(stream); // After you fix print_array
     return stream;
}


Also note that a method that access data but does not modify the state of the object should be marked const. So the signature should be: void print_array() const

Are the following members really part of the array?

void merge_recurse(int left, int right)
int merge_sort()
void quick_recurse(int left, int right)


OK. Lets assume they are for now.
Then  void merge_recurse(int left, int right) should be a private member. There should be no reason to call this from externally.

  scratch = new T[size]();
  if(scratch != NULL)


scratch will Never be NULL.

I think merge (in merge_recurse) is easier to write than you are making it:

    int index = 0;
    int l = left;
    int r = midpoint;
    while((l &lt; midpoint) &amp;&amp; (r &lt; right))
    {
      scratch[index++] = (array[l] &gt; array[r]))
                           ? array[l++]
                           : array[r++];
    }
    // One of the two ranges is empty.
    // copy the other into the destination.
    while(l &lt; midpoint)
    {
        scratch[index++] = array[l++];
    }
    while(r &lt; right)
    {
        scratch[index++] = array[r++];
    }


You should only call srand() once in an application:

void rand_to_array()
  {
  srand(time(NULL));


By putting srand() inside the structure you are opening it up to be called multiple times. Call it once just after main() then don't call it again.

When you can use the standard tools:

      tmp = array[l];
      array[l] = array[r];
      array[r] = tmp;


Can be replaced with:

 std::swap(array[l], array[r]);


I am relatively sure these two are wrong:

  while (l &lt;= r)
    if (l &lt;= r) 


They should be:

  while (l &lt; r)
    if (l &lt; r)