How can I optimize this mergesort? In main:

for(int i = 1; i &lt; upto; i *= 2)
    {  for(int j = 0; j &lt; (upto - i); j += (2*i))
       {  int end2 = (2*i &lt; (upto - j)) ? 2*i : upto - j;
          mymerge(&amp;(array[j]), i, end2); }  }


Merge:

void mymerge(people  *arr, int end1, int end2){
  int i = 0;
  int j = end1;
  int k = 0;
  people * temp = new people[end2];

  while(i &lt; end1 &amp;&amp; j &lt; end2){
    if(arr[i].lname &lt; arr[j].lname){
        temp[k] = arr[i];
        i += 1;
    }else if(arr[i].lname &gt; arr[j].lname){
        temp[k] = arr[j];
        j += 1;
    }else if(arr[i].fname &lt; arr[j].fname){
        temp[k] = arr[i];
        i += 1;
    }else if(arr[i].fname &gt; arr[j].fname){
        temp[k] = arr[j];
        j += 1;
    }else if(arr[i].dob &lt; arr[j].dob){
        temp[k] = arr[i];
        i += 1;
    }else if(arr[i].dob &gt;= arr[j].dob){
        temp[k] = arr[j];
        j += 1; }

   k += 1;
 }

  while( i &lt; end1){
    temp[k] = arr[i];
    i +=1; k +=1; }

  while(j &lt; end2){
    temp[k] = arr[j];
    j += 1; k += 1; }

  for(int c = 0; c &lt; end2; c += 1)
    arr[c] = temp[c];

  delete [] temp;
}


Would a recursive or iterative approach improve run time? Is there a better way to use pointers? This would be for an array that is not likely to be in any partially sorted order.
First you should define your ordering separately from your merge:

bool operator&lt;(people const&amp; lhs, people const&amp; rhs)
{
    if (lhs.lname &lt; rhs.lname)  {return true;}
    if (lhs.lname &gt; rhs.lname)  {return false;}

    // lhs.lname == rhs.lname 
    if (lhs.fname &lt; rhs.fname)  {return true;}
    if (lhs.fname &gt; rhs.fname)  {return false;}

    // lhs.lname == rhs.lname  &amp;&amp; lhs.fname == rhs.fname
    if (lhs.dob &lt; rhs.dob)      {return true;}

    // Optimize away the last test.
    //if (lhs.dob &gt; rhs.dob)      {return false;}

    return false;
}


Incrementing by one can be done with the operator++

j += 1;
// Easier to write as:
++j;


Or you can do it in-place with:

temp[k] = arr[i];
i += 1;
// Easier to write as
temp[k] = arr[i++];


Using new/delete is a bad idea. It makes you do all the memory management. It is better to use classes that do it all for you. In your case std::vector is a better choice for memory management of arrays

people * temp = new people[end2];
....
delete [] temp;
// Better to use std::vector
std::vector&lt;people&gt;  temp(end2);
....


Prefer to use standard algorithms rather than manual loops.

  for(int c = 0; c &lt; end2; c += 1) {
    arr[c] = temp[c];
  }
  // Use std::copy
  std::copy(temp.begin(), temp.end(), arr);


If you are copying something and not going to use the original again. Then try and move the object to the destination rather than copying it.

  temp[k] = arr[i];
  // Prefer to move rather than copy
  // if you are not going to use the value at arr[i] again.
  temp[k] = std::move(arr[i]);

  // Note this assumes you have defined move constructor and move assignment operator
  // for the class people. If you have not defined these operations then it will
  // default to use the normal copy versions.


Now your merge becomes more readable:

void mymerge(people  *arr, int end1, int end2)
{
  int i = 0;
  int j = end1;
  std::vector&lt;people&gt;  temp;
  temp.reserve(end2);

  while(i &lt; end1 &amp;&amp; j &lt; end2)
  {
      people&amp;  src =  (arr[i] &lt; arr[j])
                         ? arr[i++]
                         : arr[j++];
      temp.emplace_back(std::move(src));
  }

  std::move(&amp;arr[i], &amp;arr[end1], std::back_inserter(temp));
  std::move(&amp;arr[j], &amp;arr[end2], std::back_inserter(temp));

  std::move(temp.begin(), temp.end(), arr);
}


Now that I have cleaned up the mymerge() function I can understand what you are doing and it looks like it should work. But it requires the input sections to be already pre-sorted. I am not sure how your double loop in main() achieves this.