关于#c++#的问题:归并排序和堆排序的关键字比较次数和记录的移动次数怎么找呀

归并排序和堆排序的关键字比较次数和记录的移动次数怎么找呀


```c++
//堆排序

// 只是找到当前数据节点的位置(让当前根节点都比自己的两个孩子大)
void heap_siftdown(int a[],int n,int p) { //调整算法
    int i = p,j = i*2+1;      //j是i的左子节点
    int tmp = a[i];          //tmp是临时变量
    while(j < n)             //适用于多层树
    {
        if(j+1 < n && a[j] < a[j+1])
            j++;
        if(a[j] <= tmp)         //如果当前根比两个孩子都大了,则break,tmp是虚拟的当前节点
            break;
        else
        {
            a[i] = a[j];          //将大孩子给当前根
            i = j;j = j*2+1;
        }
    }
    a[i] = tmp; 
}
void HeapSort(int a[],int n)
{
    int i;
    for(i = (n-1)/2; i >= 0;i--) //(n-1)/2最右边有子孩子那个节点
        heap_siftdown(a, n, i);
    for(i = n;i >= 0; i--)     //每一次将最大的换到末尾,再重排前面的剩下的
    {
        swap(a[i], a[0]);
        heap_siftdown(a, i, 0); //自顶向下重排
    }
}
//归并排序

void Merge(int *arr, int n){
    int temp[n];    // 辅助数组
    int b = 0;  // 辅助数组的起始位置
    int mid = n / 2;    // mid将数组从中间划分,前一半有序,后一半有序
    int first = 0, second = mid;    // 两个有序序列的起始位置
     
    while (first < mid && second < n){
        if (arr[first] <= arr[second]){  // 比较两个序列
            
            temp[b++] = arr[first++];
            
        }
            
        else{
  
            temp[b++] = arr[second++];
            
        }
            
    }
 
    while(first < mid){ // 将剩余子序列复制到辅助序列中
        temp[b++] = arr[first++];
    }              
    while(second < n){
        temp[b++] = arr[second++];
    }
    for (int i = 0; i < n; i++){    // 辅助序列复制到原序列
        arr[i] = temp[i];
    }
}
void MergeSort(int *arr, int n){
    if (n <= 1)    // 递归出口
        
        return;
    if (n > 1){
        MergeSort(arr, n / 2);    // 对前半部分进行归并排序
        MergeSort(arr + n / 2, n - n / 2);    // 对后半部分进行归并排序
        Merge(arr, n);    // 归并两部分
    }
}

```