I am trying to run the following code for quicksort but the output is always a garbage value.What should be the modification in the code? - c++

this is the following code
#include<iostream>
using namespace std;
int findPivot(int a[],int startIndex,int endIndex)
{
int pivot=a[endIndex];
int pivotIndex=startIndex;
for(int i=0;i<endIndex-1;i++)
{
if(a[i]<pivot)
{
int temp=a[i];
a[i]=a[pivotIndex];
a[pivotIndex]=a[i];
pivotIndex++;
}
}
int temp=pivot;//swapping pivot element into its position.
pivot=a[pivotIndex];
a[pivotIndex]=temp;
return pivotIndex;
}
void quickSort(int a[],int startingIndex,int endingIndex)
{
int number;
if(startingIndex < endingIndex)
{
int returnValueOfPivot= findPivot(a,startingIndex,endingIndex);
//cout<<returnValueOfPivot<<endl;
quickSort(a,startingIndex,returnValueOfPivot-1);//sorting for left
quickSort(a,returnValueOfPivot+1,endingIndex);//sorting for right
}
}
int main()
{
int number;
cout<<"Enter the total number of elements"<<endl;
cin>>number;
cout<<"Enter the values"<<endl;
int a[number-1];
for(int i=0;i<number;i++)
{
cin>>a[i];
}
quickSort(a,0,number-1);
for(int i=0;i<number;i++)
{
cout<<a[i]<<",";
}
return 1;
}

There are three major problems in your code :
int a[number-1];
You are allocating 1 less space for your array. Note that, array index starts from 0. So array of 5 numbers will be like
array[5] : array[0],array[1],array[2],array[3],array[4]
Swapping array values :
int temp=pivot;//swapping pivot element into its position.
pivot=a[pivotIndex];
a[pivotIndex]=temp;
Here, you swapped pivot value with a[pivotIndex] not a[endIndex]!!
So the correct swap would have been :
int temp=a[endIndex];//swapping pivot element into its position.
a[endIndex]=a[pivotIndex];
a[pivotIndex]=temp;
for(int i=0;i<endIndex-1;i++) is incorrect loop
correct loop would be :
for(int i=startIndex;i<=endIndex-1;i++)
You need to start from the start index and end till the end index. You are currently going from 0 to end - 1. [Think of the right side array loop, it won't start with 0]
Make these changes and your code will work.

Related

The output of this question is correct but i am getting a segmentation error

I am trying to solve the program of array rotation. I am getting segmentation error in the code. Can someone please tell where is the problem in this code?
this is the question
Given an unsorted array arr[] of size N, rotate it by D elements (clockwise).
The first line of the input contains T denoting the number of testcases. First line of each test case contains two space separated elements, N denoting the size of the array and an integer D denoting the number size of the rotation. Subsequent line will be the N space separated array elements.
and i have solved it with the following code.
#include <iostream>
using namespace std;
int* rotate(int ar[],int n, int m)
{static int temp[100];
for(int i =0;i<m;i++)
{
temp[i]=ar[i];
}
for(int j =m;j<n;j++)
{
ar[j-m]=ar[j];
}
int x=0;
for(int k =n-m;k<n;k++)
{
ar[k]=temp[x];
x++;
}
return ar;
}
int main() {
//code
int t, n , m;
cin>>t;
while(t>0)
{
cin>>n>>m;
int arr[n];
int * ptr;
for(int i = 0 ;i<n;i++)
{
cin>>arr[i];
}
ptr=rotate(arr,n,m);
for(int j=0;j<n;j++)
cout<<ptr[j]<<" ";
cout<<endl;
t--;
}
return 0;
}
If m > n then it crashes in the first for() loop in rotate as you index past the end of arr.
If m < 0 it crashes in the 2nd loop as it index before arr.
There are probably more cases.

getting error while trying to rotate array clock wise using stack

Given an unsorted array arr[] of size N, rotate it by D elements (clockwise).
Input
The first line of the input contains T denoting the number of testcases. First line of each test case contains two space separated elements, N denoting the size of the array and an integer D denoting the number size of the rotation. Subsequent line will be the N space separated array elements
Output
For each testcase, in a new line, output the rotated array
Example
Input
1 2 3 4 5
Output
3 4 5 1 2
#include <iostream>
#include <stack>
using namespace std;
void rotate(int *a,int s,int r) {
stack<int> st;
for(int i=0;i<r;i++) {
st.push(a[i]);
}
for(int j=r;j<s;j++) {
a[j-r] = a[j];
}
for(int k=s-1;k>r+1;k--) {
a[k] = st.top();
st.pop();
}
for(int l=0;l<s;l++) {
cout<<a[l]<<" ";
}
}
int main() {
//code
int T;
cin>>T;
while(T--) {
int N,r;
cin>>N>>r;
int A[N];
for(int i=0;i<N;i++) {
cin>>A[i];
}
rotate(A,N,r);
cout<<endl;
}
return 0;
}
I followed your logic, it seems like there is problem in your backfill part.
for(int k=s-1;k>=s-r;k--) { // change k>r+1 to k>=s-r
a[k] = st.top();
st.pop();
}
sorry my bad, int third for loop in rotate function there should be k>s-r-1

I am getting garbage values in my Merge Sort code

I am trying to implement merge sort algorithm in C++. This is my code.Logic seems to be fine.
But the output I'm getting is garbage values.I'm not able to get where the problem is in the code.
I think my logic is correct but I'm not sure.
#include <iostream>
using namespace std;
void Merge(int A[],int L[],int nL,int R[],int nR);
void MergeSort(int A[]);
//Function to Merge Arrays L and R into A.
//nL = number of elements in L
//nR = number of elements in R.
void Merge(int A[],int L[],int nL,int R[],int nR)
{
// i - to mark the index of left subarray (L)
// j - to mark the index of right sub-raay (R)
// k - to mark the index of merged subarray (A)
int i=0;
int j=0;
int k=0;
while(i<nL && j<nR)
{
if(L[i]<=R[i])
{ A[k]=L[i];
i=i+1;
}
else
{ A[k]=R[j];
j=j+1;
}
k=k+1;
}
while(i<nL)
{ A[k]=L[i];
i=i+1;
k=k+1;
}
while(j<nR)
{ A[k]=R[j];
j=j+1;
k=k+1;
}
}
// Recursive function to sort an array of integers.
void MergeSort(int A[],int n)
{
if (n<2) return;//base condition.If the array has less than two
//elements, do nothing
int mid=n/2;
// create left and right subarrays
// mid elements (from index 0 till mid-1) should be part of left sub-
//array
// and (n-mid) elements (from mid to n-1) will be part of right sub-
//array
int left[mid];
int right[n-mid];
for(int i=0;i<mid-1;i++) left[i]=A[i];// create left subarray
for(int i=mid;i<n-1;i++) right[i-mid]=A[i];// create right subarray
MergeSort(left,mid);
MergeSort(right,n-mid);
Merge(A,left,mid,right,n-mid);
}
int main()
{ int A[]={2,4,7,1,5,3};
int n=sizeof(A)/sizeof(A[0]);
MergeSort(A,n);
for(int i=0;i<n;i++) cout<<A[i]<<" ";
return 0;
}
Expected output is 1 2 3 4 5 7
But actual is 0 -785903160 1 0(every time it's different)
This has been answered at, how-to-implement-classic-sorting-algorithms-in-modern-c. But I thought I'd post an answer that beginners my find valuable as I've seen this asked many times in the past. It must be a popular homework question.
In my opinion, if this is a modern C++ assignment, there should be a lot less of using indexing.
So in this implementation, I have not used std::merge and wrote the merge so some method could be seen.
Avoid the idiom: using namespace std; Why it is taught is beyond me. Typedef your types, it is much clearer.
using data_vect = std::vector<int>;
Hopefully this is clear enough and completely done with iterators. It is not as efficient as possible, the push_back in Merge could be avoided among other things. I DuckDucked this sort and the first few hits were not that great.
#include <iostream>
#include <vector>
using data_vect = std::vector<int>;
using dv_iter = data_vect::iterator;
data_vect Merge(data_vect& first, data_vect& second)
{
data_vect result;
dv_iter fval = first.begin();
dv_iter sval = second.begin();
for (;fval != first.end() || sval != second.end();)
{
if (fval == first.end())
result.push_back(*sval++);
else if (sval == second.end())
result.push_back(*fval++);
else if (*fval < *sval)
result.push_back(*fval++);
else
result.push_back(*sval++);
}
return result;
}
void MergeSort(data_vect& input)
{
int half = input.size() / 2;
if (! half)
return;
data_vect left(input.begin(), input.begin() + half );
data_vect right(input.begin() + half, input.end());
MergeSort(left);
MergeSort(right);
input = Merge(left, right);
}
int main()
{
data_vect A = { 6,2,7,4,1,5,3 };
MergeSort(A);
for ( auto& val : A )
std::cout << val << " ";
return 0;
}
Although understandable,
it is not possibile in C++ to declare an array with a variable size, e.g. int[mSize].
All arrays must have a constant size, e.g. int[10] or
const int mSize = 10;
int[mSize] mArray...
You want a storage container which has a variable size. as #PaulMcKenzie suggested,
you might want to use a Vector object. Your code would look something like this:
#include <iostream>
#include <vector>
using namespace std;
void Merge(vector<int>& A, vector<int>& L, vector<int>& R);
void MergeSort(vector<int>& A);
//Function to Merge Arrays L and R into A.
void Merge(vector<int>& A, vector<int>& L, vector<int>& R)
{
// i - to mark the index of left subarray (L)
// j - to mark the index of right sub-raay (R)
// k - to mark the index of merged subarray (A)
unsigned int i=0;
unsigned int j=0;
unsigned int k=0;
while(i<L.size() && j<R.size())
{
if(L[i]<=R[i])
{ A[k]=L[i];
i=i+1;
}
else
{ A[k]=R[j];
j=j+1;
}
k=k+1;
}
while(i<L.size())
{ A[k]=L[i];
i=i+1;
k=k+1;
}
while(j<R.size())
{ A[k]=R[j];
j=j+1;
k=k+1;
}
}
// Recursive function to sort an array of integers.
void MergeSort(vector<int>& A)
{
int n = A.size();
if (n<2) return;//base condition.If the array has less than two
//elements, do nothing
int mid=n/2;
// create left and right subarrays
// mid elements (from index 0 till mid-1) should be part of left sub-
//array
// and (n-mid) elements (from mid to n-1) will be part of right sub-
//array
vector<int> left(mid);
vector<int> right(n-mid);
for(int i=0;i<mid;i++) left[i]=A[i];// create left subarray
for(int i=mid;i<n;i++) right[i-mid]=A[i];// create right subarray
MergeSort(left);
MergeSort(right);
Merge(A,left,right);
}
int main()
{ vector<int> A={2,4,7,1,5,3};
MergeSort(A);
for(unsigned int i=0;i<A.size();i++) cout<<A[i]<<" ";
return 0;
}
[Edit]
I noticed I accidentally used comma's instead of dots in vector.size() calls. Also, I noticed 2 arrays stopping one item too early in copying left and right vectors.
Your code did not work. Above code compiles fine, but produces 1 3 5 2 4 7 as output. Also, have you thought of a vector of uneven length, such as 5 4 3 2 1?
At this point, the code will not split properly

My code runs fine when I debug it, but crashes as soon as I run it

I have been asked to built a K sorted array by my professor and then sort it using minheap. A k sorted array is basically an array where each element is at most K positions away from the location it would be if the array was fully sorted in ascending order. For instance, if K=3, the element at position i=8 can be at locations 5, 6, 7, 8, 9, 10, or 11 in the fully sorted arrayI'm stuck in the first part of the problem.
Requirements:
Allow the user to enter a number of (N) elements and the number K.
Produce a K-sorted array based on the user input (more than one K-sorted array can be produced; randomly pick one). Display it.
After rigorous thinking I built the below code for K Sorting:
void kSortedArray:: displayKSorted()
{
cout<<"Please enter the no. of elements you want to KSort: ";
cin>>N;
cout<<"Please enter the value for K: ";
cin>>K;
int i=0;
while (i<N)
{
cout<<"Enter element "<<i+1<<" : ";
cin>>arr[i++];
}
insertion_sort(arr,N);
srand(time(NULL));
int output=0;
i=0;
int maxRand=0;
int minRand=0;
int arr2[N];
int a=0;
int found=0;
int found1=0;
int range=0;
int count1=0;
vector<int>:: iterator it1;
vector<int>:: iterator it2;
vector<int> arr3;
while(kSortedIndex.size()<N)
{
minRand=range-K;
maxRand=range+K;
output = minRand + (rand() % (maxRand - minRand + 1));
if (output<0)
{
output=N+output;
}
if(output>N-1)
{
output=output-N;
}
//arr2[i]=output;
for(it1=kSortedIndex.begin();it1!=kSortedIndex.end();it1++)
{
if(*it1==output)
{
found=1;
for(it2=arr3.begin();it2!=arr3.end();it2++)
{
if(*it2==output)
{
found1=1;
break;
}
}
if(found1==0)
{
arr3.push_back(output);
count1++;
}
break;
}
}
if(found==0)
{
kSortedIndex.push_back(output);
count1=0;
arr3.clear();
range++;
}
found=0;
found1=0;
if (count1>((2*K)+1))
{
range--;
count1=0;
}
if(range>(N-1))
range--;
}
vector<int>::iterator it;
int j=0;
// i=0;
for(it=kSortedIndex.begin();it!=kSortedIndex.end();it++)
{
arr2[*it]=arr[j];
j++;
//cout<<arr2[j++];
}
for(j=0;j<N;j++)
{
cout<<arr2[j];
}
}
Below is the header file:
class kSortedArray
{
public:
kSortedArray();
void displayKSorted();
protected:
private:
int N=0;
int K=0;
int* arr=new int [N];
createKSorted();
void insertion_sort(int arr[],int length);
vector <int> kSortedIndex;
};
Could someone please help me to figure out why my code crashes when I run it and runs fine when I debug it. Is it a memory leak issue? I even tried deleting arr, arr2 and clearing arr3 but that isn't working (code still cashes). Your help much appreciated.
The declaration int* arr=new int [N]; in the header is wrong. You cannot allocate memory for the array here because you do not yet know the value for N. That value will be known only after cin>>N; in the kSortedArray:: displayKSorted function. Therefore you need to do allocate memory there:
void kSortedArray:: displayKSorted()
{
cout<<"Please enter the no. of elements you want to KSort: ";
cin>>N;
arr = new int [N]; // <<< add this line
cout<<"Please enter the value for K: ";
cin>>K;
int i=0;
...
Header:
...
private:
int N=0;
int K=0;
int* arr; // =new int [N]; <<< remove the allocation
createKSorted();
void insertion_sort(int arr[],int length);
...
Disclaimer: This is non tested non error checking code, and there may be more problems.

Linear search algorithm

The goal of my program is to find the number entered by user in an array of integers (array was created automatically), and to show the index of this number (or numbers, if they occurs several times). It works correctly when the desired number occurs only once in array. For example, if there is an array
7 8 0 4 2 7 2
and user entered "8", the output of program will be
Index of the number you entered is: 2
But when we have array:
0 5 3 9 3 7 2
And the user entered "3", the output will be
Index of the number you entered is: 3
And I wonder how to make the program include second "3" number which has index 5. The code of program:
#include <iostream>
#include <ctime>
#include <stdlib.h>
using namespace std;
int i, N;
int LinearSearch(int Array[], int searchValue)
{
for (i=0; i<N; i++)
{
if (Array[i]==searchValue)
return i;
}
return -1;
}
int main()
{
int searchValue, Array[1000];
cout<<"Size of array: ";
cin>>N;
cout<<"Array: ";
for (i=0; i<N; i++)
{
Array[i]=rand()%10;
cout<<Array[i]<<" ";
}
cout<<"Search value: ";
cin>>searchValue;
if (LinearSearch(Array, searchValue)==1)
cout<<"\nIndex of the number you entered is: "<<LinearSearch(Array, searchValue)+1;
else
cout<<"\nNothing found";
}
You can do it in two ways:
1. Change the LinearSearch's return value to vector, write it like this:
vector<int> LinearSearch(int Array[], int searchValue)
2.Add a vector reference variable in the parameters, it should like this:
int LinearSearch(int Array[], int searchValue, vector<int> &results)
And the the method body in LinearSearch should have little change accordingly.
Because you return from the search function as soon as the value is located:
for (i=0; i<N; i++)
{
if (Array[i]==searchValue)
return i; // <-- as soon as we get here, we break the loop
}
therefore, you will get the first position in which searchValue is located, which is 2 (0-based). Thus, you get 2+1 = 3. To get the last one, you will have to remove the early exit, and keep the current index in a variable, like this:
int LinearSearch(int Array[], int searchValue) {
int index = -1;
for (i = 0; i < N; i++) {
if (Array[i]==searchValue) {
index = i;
}
}
return index;
}