在我的合并排序实现中找不到错误,得到错误的输出?

Can't find error in my merge sort implementation, getting wrong output?

在下面的代码中,未排序的数组必须找到第 k 个最小的 给定一个数组 arr[] 和一个整数 K,其中 K 小于数组的大小,任务是在给定数组中找到第 K 个最小的元素。假定所有数组元素都是不同的。


#include<bits/stdc++.h>
using namespace std;

合并函数:


void merge(int arr[],int l,int m,int r){
    int marr[(r-l)+1];
    int i=l,j=m+1,k=0;
    for(k;k<=(r-l);k++){
        if(i==(m+1)){
            marr[k]=arr[j];
            j++;
        }
        else if(j==(r+1)){
            marr[k]=arr[i];
            i++;
        }
        else if(arr[i]<=arr[j]){
            marr[k]=arr[i];
            i++;
        }
        else if(arr[i]>arr[j]){
            marr[k]=arr[j];
            j++;
        }
    }
    //Below assignment was creating wrong output but cant figure out why?
    for(k=0;k<=(r-l);k++,l++){
         arr[l]=marr[k];
     }
//However below code worked instead, in spite tracing same no. of values
//for(int x=l,k=0;x<=r;x++,k++){
        
      //  arr[x]=marr[k];
//}

合并排序:

void mergesort(int arr[], int l,int r){
    if(r<=l)
    return;
    int mid=l+(r-l)/2;
    mergesort(arr,l,mid);
    mergesort(arr,mid+1,r);
    merge(arr,l,mid,r);
} 

class Solution{
    public:
    // arr : given array
    // l : starting index of the array i.e 0
    // r : ending index of the array i.e size-1
    // k : find kth smallest element and return using this function
    int kthSmallest(int arr[], int l, int r, int k) {
    
        mergesort(arr,l,r);
   
        return arr[k-1];
        
        

    }
};

Driver代码开始

int main()
{
    int test_case;
    cin>>test_case;
    while(test_case--)
    {
        int number_of_elements;
        cin>>number_of_elements;
        int a[number_of_elements];
        
        for(int i=0;i<number_of_elements;i++)
            cin>>a[i];
            
        int k;
        cin>>k;
        Solution ob;
        cout<<ob.kthSmallest(a, 0, number_of_elements-1, k)<<endl;
    }
    return 0;
}  

Driver代码结束

尽管 non-standard 可变长度数组和其他注意事项(说真的,得到一本好的参考书和有信誉的教程指南),问题出在你的合并算法中:

在合并结束时,您试图将排序后的 marr 数据放回 arr。这是在这里完成的:

for(k=0;k<=(r-l);k++,l++)
{
    arr[l]=marr[k];
}

问题是 l 的增量,它具有 缩短 合并的效果,因为它导致 (r-l) 向 [=16= 折叠],而 k 正在向上上升。这意味着您不会复制所有数据,并且只剩下 not-only 部分排序,您在 arr 中留下了潜在的重复垃圾(事实上,很有可能)。

将其替换为:

for (i=0; i<=(r-l); ++i)
{
    arr[i+l] = marr[i];
}

应该会为您解决。这从 0.. 段长度开始运行 i,包括在内,将结果放入调整后的偏移量 i+l 位置。

此代码中的所有错误或不足之处都已在评论中巧妙地提及,所以我将把它留给您解决(相信我,您想要解决所有问题)。