在我的合并排序实现中找不到错误,得到错误的输出?
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
位置。
此代码中的所有错误或不足之处都已在评论中巧妙地提及,所以我将把它留给您解决(相信我,您想要解决所有问题)。
在下面的代码中,未排序的数组必须找到第 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
位置。
此代码中的所有错误或不足之处都已在评论中巧妙地提及,所以我将把它留给您解决(相信我,您想要解决所有问题)。