binary search segmentation fault in c++ - c++

This works fine...the size of the array is just 7.
// item = search item
int bin(int arr[], int item, int startIndex, int endIndex)
{
if(startIndex <= endIndex)
{
int middle = 1 + (endIndex - startIndex) / 2;
if(item == arr[middle]) return middle;
if(item < arr[middle])
return bin(arr, item, startIndex, middle-1);
return bin(arr, item, middle + 1, endIndex);
}
return -1;
}
int main()
{
int sample[] = {1,2,3,4,5,6,7};
cout<< bin(sample,5,0,6) <<endl;
system("pause");
}
But after increasing the size of array and searching 19...it says segmentation fault.
int main()
{
int sample[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22};
// size of array is 22
cout<< bin(sample,19,0,21) <<endl;
system("pause");
}
Why is it like that? Do I have a semantic error?

Your middle calculation is wrong:
int middle = 1 + (endIndex - startIndex) / 2;
should be:
int middle = startIndex + (endIndex - startIndex) / 2;

You can use the following code:
#include <iostream>
using namespace std;
void Binary(int arr[], int n, int key)
{
int s = 0;
int e = n - 1;
while (s <= e) {
int mid = (s + e) / 2;
if (arr[mid] == key) {
cout << "Element Found At Index No. " << mid;
} else if (arr[mid] > key) {
e = mid - 1;
} else {
s = mid + 1;
}
}
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int key;
cout << "Enter element to be searched!";
cin >> key;
Binary(arr, n, key);
return 0;
}

Related

C++ program goes into a never-ending input cycle

This is a simple binary search program, but for some reason, the program just doesn't move on after asking for the value of the key from the user. At first, I thought it is an issue with my compiler, but it still happens wherever I paste the code, and I don't know why.
#include <iostream>
using namespace std;
int binary(int arr[], int n, int k){
int s = 0;
int e = n;
int mid = (s+e)/2;
while(s<=e){
if(k==arr[mid]){
return mid;
}
else if(k>arr[mid]){
s = mid+1;
}
else if(k<arr[mid]){
e = mid-1;
}
}
return -1;
}
int main(){
int i, n, key;
cin>>n;
int a[n];
for(i=0;i<n;i++){
cin>>a[i];
}
cout<<"Enter key:"<<endl;
cin>>key;
cout<< binary(a, n, key);
}
Instead of moving on after k, the code just does nothing.
you code is looping in the 'binary ' function
try this to see
while(s<=e){
cout << s << e; <<<=====
learn to use your debugger to step through the code
The middle element is found inside the loop in binary search because the search interval is reduced to half in every iteration.
Your mid is not changing that is why the program is not terminating.
So final code after correction is:
#include <iostream>
using namespace std;
int binary(int arr[], int n, int k)
{
int s = 0;
int e = n;
while (s <= e)
{
int mid = (s + e) / 2;
if (k == arr[mid])
{
return mid;
}
else if (k > arr[mid])
{
s = mid + 1;
}
else if (k < arr[mid])
{
e = mid - 1;
}
}
return -1;
}
int main()
{
int i, n, key;
cin >> n;
int a[n];
for (i = 0; i < n; i++)
{
cin >> a[i];
}
cout << "Enter key:" << endl;
cin >> key;
cout << binary(a, n, key);
}

Blank output screen when I run this searching algorithm

I have been practicing median search algorithm, and this is what I wrote-
#include <iostream>
#include <stdlib.h>
using namespace std;
int S1[10] = { 0 };
int S2[1] = { 0 };
int S3[10] = { 0 };
int mediansearch(int A[], int k, int size)
{
int ran = rand() % size;
int i = 0;
int a = 0;
int b = 0;
int c = 0;
for (i = 0; i < size; i++)
{
if (A[ran] > A[i])
{
S1[a] = A[i];
a++;
}
else if (A[ran] == A[i])
{
S2[b] = A[i];
b++;
}
else
{
S3[c] = A[i];
c++;
}
}
if (a <= k)
{
return mediansearch(S1, k, a);
}
else if (a + b <= k)
{
return A[ran];
}
else
{
return mediansearch(S3, k - a - b, c);
}
}
int main()
{
int arr[] = { 6, 5, 4, 8, 99, 74, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int x = mediansearch(arr, 5, n);
cout << "5th smallest is:" << x << endl;
}
And I have been getting output as-
Process returned -1073741676 (0xC0000094) execution time : 1.704 s
So, what am I doing wrong? Any kind of help will be appreciated.
There are a few issues with this code, the first one being the naming of variables.
I suggest you choose more significative names in the future, because good naming is fundamental when someone else has to understand your code and your ideas.
Another thing is that the arguments of are in a counterintuitive order because the pair related to the array are separated by the index you want to look for.
I'd write int mediansearch(int A[], int size, int k)
Here the comparisons are reversed, k should be less than rather than greater than equal a
if (a <= k) // (k < a)
{
return mediansearch(S1, k, a);
}
else if (a + b <= k) // (k < a + b)
{
return A[ran];
}
else
{
return mediansearch(S3, k - a - b, c);
}
The other thing is that you're sharing S1, S2, and S3 among all the recursive calls and that causes some error that I wasn't able to identify, maybe someone commenting will help me out.
However, I suggest you read this article that explains in detail the procedure you're trying to implement: https://rcoh.me/posts/linear-time-median-finding/
It's python, but it can be easily ported to C/C++, and in fact that's what I did.
#include <iostream>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
using namespace std;
int medianSearch(int A[], int size, int k)
{
int *lows = (int *)calloc(size, sizeof(int));
int lowsLen = 0;
int *highs = (int *)calloc(size, sizeof(int));
int highsLen = 0;
int *pivots = (int *)calloc(size, sizeof(int));
int pivotsLen = 0;
int median;
int pivot;
int i;
if (size == 1)
return A[0];
// Other ways of randomly picking a pivot
// pivot = 0;
// pivot = size-1;
// pivot = size/2;
assert(size > 0);
pivot = rand() % size;
for (i = 0; i < size; ++i)
{
if (A[i] < A[pivot])
{
lows[lowsLen] = A[i];
lowsLen++;
}
else if (A[i] > A[pivot])
{
highs[highsLen] = A[i];
highsLen++;
}
else
{
pivots[pivotsLen] = A[i];
pivotsLen++;
}
}
if (k < lowsLen)
median = medianSearch(lows, lowsLen, k);
else if (k < lowsLen + pivotsLen)
median = A[pivot];
else
median = medianSearch(highs, highsLen, k - lowsLen - pivotsLen);
free(lows);
free(highs);
free(pivots);
return median;
}
int compare(const void *a, const void *b)
{
return ( *(int *)a - *(int *)b );
}
int medianSorted(int A[], int size, int k)
{
qsort(A, size, sizeof(int), compare);
return A[k];
}
#define N 1000
int main()
{
int arr[N];
int brr[N];
int n = sizeof(arr) / sizeof(arr[0]);
int k = 200;
int x;
int y;
for (int i = 0; i < n; ++i)
arr[i] = brr[i] = rand();
x = medianSearch(arr, n, (k-1)%n);
y = medianSorted(brr, n, (k-1)%n);
string suffix;
switch (k % 10)
{
case 1: suffix = "st"; break;
case 2: suffix = "nd"; break;
case 3: suffix = "rd"; break;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 0: suffix = "th"; break;
}
cout << k << suffix << " smallest is: " << x << endl;
cout << k << suffix << " smallest is: " << y << endl;
}
https://onlinegdb.com/HJc2V6Lbu

C++ Divide and conquer algorithm problems

I have just learnt about Divide and Conquer algorithm and I'm a little bit confused about it. The question is my homework, I have tried many ways to fix my code but it did not run.
#include <iostream>
using namespace std;
void inputArray(int* a, int& n)
{
cout << "Input n:";
cin >> n;
for (int i = 0; i < n; i++)
{
cout << "input a[" << i << "]= ";
cin >> a[i];
}
}
int sumeven(int* a, int l, int r)
{
if (l == r && a[l] % 2 == 0)
{
return a[l];
}
int mid = (l + r) / 2;
int s1 = sumeven(a, l, mid);
int s2 = sumeven(a, mid + 1, r);
return s1 + s2;
}
int main()
{
int n;
int a[20];
inputArray(a, n);
cout<<sumeven(a, 0,n-1);
return 0;
}
Try to test your programs without user input first:
#include <iostream>
using namespace std;
int sumeven(int* a, int l, int r)
{
if (r >= 6) return 0;
if (l > r ) return 0;
if (l >= r)
{
if (a[l] % 2 == 0)
{
return a[l];
}
else
{
return 0;
}
}
int mid = (l + r) / 2;
int s1 = sumeven(a, l, mid);
int s2 = sumeven(a, mid + 1, r);
return s1 + s2;
}
int main()
{
int n=6;
int a[6]={1,2,3,48,5,6};
cout<<sumeven(a,0,n-1);
return 0;
}

Why is this Quick Sort implementation giving a weird output

My Quick Sort is giving a weird output.Some sections of the output are sorted while some some sections are just random.I am using pivot element to partition the array recursively using partition function into 2 halves with the left half elements less than the pivot element and right half elements greater than the pivot element.
#include <iostream>
using namespace std;
int partition(int *arr, int start, int end)
{
int pivot = start;
int temp;
int temp2;
while (start < end)
{
while (arr[start] <= arr[pivot])
start++;
while (arr[end] > arr[pivot])
end--;
if (start < end)
{
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
temp2 = arr[pivot];
arr[pivot] = arr[end];
arr[end] = temp2;
return end;
}
void quickSort(int input[], int size)
{
int lb = 0;
int ub = size - 1;
int loc;
if (lb < ub)
{
loc = partition(input, lb, ub);
quickSort(input, loc - 1);
quickSort(input + loc + 1, ub - loc);
}
else
return;
}
int main()
{
int n;
cin >> n;
int *input = new int[n];
for (int i = 0; i < n; i++)
{
cin >> input[i];
}
quickSort(input, n);
for (int i = 0; i < n; i++)
{
cout << input[i] << " ";
}
delete[] input;
}
in this part when you try to sort the array from the location start to pivot you have
quickSort(input, loc - 1);
quickSort(input + loc + 1, ub - loc);
which means input[loc] is never treated since you go from 0 to loc -1 and loc +1 to end
which is corrected here
if (lb < ub)
{
loc = partition(input, lb, ub);
quickSort(input, loc );
quickSort(input + loc + 1, ub - loc);
}

Why is Quicksort using Dutch National Flag partition technique working slower than a normal Quicksort?

My implementation for Quicksort using Dutch National Flag partition technique.
http://ideone.com/WgAiGG
And for a normal Quicksort.
http://ideone.com/GOE5Jl
The code for Quicksort using Dutch National Flag partition technique
#include<iostream>
#include<time.h>
using namespace std;
void partition (int *a, int s, int e, int &start, int &end)
{
start=s-1;
int mid=s;
end=e;
int pivot=a[e],temp,i;
while (mid < end)
{
if (a[mid] < pivot)
{
temp = a[start+1];
a[start+1] = a[mid];
a[mid] = temp;
start++;
mid++;
}
else if (a[mid] == pivot)
{
mid++;
}
else
{
temp = a[end-1];
a[end-1] = a[mid];
a[mid] = temp;
end--;
}
}
temp = a[mid];
a[mid] = a[e];
a[e] = temp;
cout<<start<<" "<<end<<"\n";
}
void Qsort(int *a, int s, int e)
{
if (s>=e)
return;
int start,end;
partition(a,s,e,start,end);
Qsort(a,s,start);
Qsort(a,end+1,e);
}
int main()
{
int a[100];
int i,j;
int n = sizeof(a)/sizeof(a[0]);
srand(time(NULL));
for (j=0;j<n;j++)
{
a[j] = rand()%40;
cout<<a[j]<<" ";
}
clock_t start = clock();
Qsort(a,0,n-1);
for (i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<"\nTime elapsed: "<<((double)clock() - start) / CLOCKS_PER_SEC<<endl;
}
The code for normal Quicksort
#include<iostream>
#include<time.h>
using namespace std;
int partition (int *a, int s, int e)
{
int i=s;
int j=e-1;
int pivot = a[e],temp;
while (i<=j)
{
if (a[i] < pivot)
{
i++;
continue;
}
if (a[j] > pivot)
{
j--;
continue;
}
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
temp = a[i];
a[i] = a[e];
a[e] = temp;
return i;
}
void qsort (int *a, int s, int e)
{
if (s>=e)
{
return;
}
int i = partition (a,s,e);
qsort(a,s,i-1);
qsort(a,i,e);
}
int main()
{
int a[100];
int i,j;
int n = sizeof(a)/sizeof(a[0]);
srand(time(NULL));
for (j=0;j<n;j++)
{
a[j] = rand()%40;
cout<<a[j]<<" ";
}
clock_t start = clock();
qsort(a,0,n-1);
for (i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<"\nTime elapsed: "<<((double)clock() - start) / CLOCKS_PER_SEC<<endl;
}