Whats wrong in this quicksort program? - c

I doubt that the there is something wrong with the partition function.
void swap(int num1, int num2) { /*function to swap the values */
int temp = intArray[num1];
intArray[num1] = intArray[num2];
intArray[num2] = temp;
}
int partition(int left, int right) { //partition function
int leftPointer = left;
int j;
int pivot=intArray[right];
for(j=0;j<right;j++){
if(intArray[j]<=pivot){
swap(j,leftPointer);
leftPointer++;
}
}
swap(leftPointer,right);
return leftPointer;
}
void quickSort(int left, int right) { //quicksort
if(left<right){
int partitionPoint = partition(left, right);
quickSort(left,partitionPoint-1);
quickSort(partitionPoint+1,right);
}
}
The program runs fine , but it doesn't sort!

Your partition algorithm always starts at element zero. It should start at the start of the partition.

Related

quicksort implementation trouble

I am encountering the problems in executing the quicksort algorithm.
THere is a error i am encountering but unable to find where the problem is. if someone could point where the error is i will be thankfull.
#include <stdio.h>
#include <stdlib.h>
void main(){
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr,0,n-1);
printArray(arr,0,n-1);
}
//Quicksort Function
void quickSort(int arr[],int low,int high){
if (low < high){
int pi=partition(arr,low,high);
quickSort(arr,low,pi-1);//takes care of lower set of numbers
quickSort(arr,pi+1,high);//takes care of higher elements above pivot
}
}
//Function for partitioing, in my program i am cosidering pivot as the element at high or the last element
int partition(int arr[],int low,int high){
int i,j;
i=(low-1);
int pivot=arr[high];
for(j=low;j<=high;j++){
if(arr[j]<=pivot){
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i+1], &arr[high]);
return (i+1);
}
//function to print array
void printArray(int arr[],int low,int high){
int i;
for(i=low;i<=high;i++){
printf("%d ",arr[i]);
}
}
//function to swap two elements of array
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
The Simple Implementation of QuickSort Algorithm
void q_sort(int v[],int left,int right)
{
int i,last;
if(left>=right)
return;
swap(v,left,(left+right)/2);
last=left;
for(i=left+1;i<=right;i++)
if(v[i]<v[left])
swap(v,++last,i);
swap(v,left,last);
q_sort(v,left,last-1);
q_sort(v,last+1,right);
}
void swap(int v[],int i,int j)
{
int temp;
if(i!=j){
temp=v[i];
v[i]=v[j];
v[j]=temp;
}
}
The problem is in this statement of your partition() -
if(arr[j]<=pivot){
Change it to -
if(arr[j]<pivot){

GCC Segmentation fault when execute quicksort code

I meet an "segmentation falut" while execute my own quick sort source code in C
in gcc version 4.4.3 with ubuntu 13
the code is look like the below
#include<stdio.h>
void Quicksort(int arr[], int start, int end);
void swap(int *a, int *b);
void main(void){
int arr[] = {15,22,13,27,12,10,20,25};
int iLength=sizeof(arr);
Quicksort(arr, 0, iLength-1);
for(int i=0;i<iLength;++i)
printf("%d", arr[i]);
}
void Quicksort(int arr[], int start, int end)
{
int left = start;
int right = end;
if((end-start)>=1)
{
int pivot = arr[start];
while(right>left)
{
while((arr[left]<=pivot)&&(left<=end)&&(right>left))//Limit check array size
left++;
while((arr[right]>pivot)&&(right>=start)&&(right>=left))
right--;
if(right>left)
swap(&arr[left], &arr[right]);
}//end while
swap(&arr[left], &arr[right]);
Quicksort(arr, start, right-1);
Quicksort(arr, right+1, end);
}//end if
else
{
return;
}
}//end Quicksort
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
I don't know what is the problem..
many web search results show that it is a memory issue..
but I don't know what is the exact problem in the above code
please help...
In main
int arr[] = {15,22,13,27,12,10,20,25};
int iLength=sizeof(arr);
This iLength will not contain length of array but its size , that is 8*4(assuming 4 bytes as size of int)= 32.
If you send this in function and use later in loop -
for(int i=0;i<iLength;++i)
printf("%d", arr[i]);
This will access index out of bound (luckily you got segmentation fault).
To calculate length of array you can do this -
int iLength = sizeof arr/sizeof(int);
And then use it .
Note - void main(void) -> int main(void) or int main(int argc,char **argv) .

How can I make this recursive Binary Search program exit and not crash if the number is not found?

How can I prevent this program from crashing if the value the user searched for is not found? (When I try to implement an if/else or count system, the program doesn't work correctly)
#include <stdio.h>
#include "simpio.h"
#include "genlib.h"
#define start 0
void bubble(int numbers[]);
int binary(int val, int numbers[], int low, int high);
void io(int numbers[]);
int size;
main()
{
int result, search;
printf("This program sorts and searches an array\n");
printf("How many numbers would you like to sort and search?\n");
size = GetInteger()-1;
int numbers[size];
printf("Enter the numbers\n");
io(numbers);
bubble(numbers);
printf("Which number would you like to search for?\n");
search = GetInteger();
result = binary(search,numbers,start,size);
printf("The number %d was found at index %d\n",search,result+1);
}
void io(int numbers[])
{
int ink;
for(ink=0;ink<=size;ink++)
{
numbers[ink] = GetInteger();
}
}
void bubble(int numbers[])
{
int first,second,count,swap;
while(TRUE)
{
for(first=0,second=1,count=0;second<=size;first++,second++)
{
if(numbers[first]>numbers[second])
{
count++;
swap = numbers[first];
numbers[first]= numbers[second];
numbers[second] = swap;
}
}
if(count==0)break;
}
}
int binary(int val, int numbers[], int low, int high)
{
int mid;
mid = (low+high)/2;
if(val==numbers[mid]||low>high) return mid;
if(val>numbers[mid]) return(binary(val,numbers,mid,high));
else if(val<numbers[mid]) return(binary(val,numbers,low,mid));
}
change to
size = GetInteger();
int numbers[size--];//change size to max index
//..
int binary(int val, int numbers[], int low, int high)
{
int mid;
if(low>high)//if not found!
return -1;//check return value at main
mid = (low+high)/2;
if(val==numbers[mid]) return mid;
if(val>numbers[mid]) return(binary(val,numbers,mid+1,high));
else if(val<numbers[mid]) return(binary(val,numbers,low,mid-1));
}

Mergesort, using a for loop to do merge

I am trying to write the code in C for mergesort using for loop in the merge function. Unfortunately it is not working. In the main function I create an array on 10 ints in descending order and then I call the mergesort function to sort them. There is obviously an error in the merge function, since the ascending order is never realized and in some array sizes some long numbers intrude. What am I doing wrong? Here's the function:
#include <stdio.h>
#include <stdlib.h>
void mergesort(int array[], int left, int right);
int main()
{
int i;
int arr[10];
for(i=10;i>0;i--){
arr[10-i]=i;
}
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
mergesort(arr,0,9);
puts("\n");
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
return 0;
}
void mergesort(int array[], int left, int right)
{
void merge(int array[],int left, int mid, int right);
int mid;
if(left<right){
mid=(left+right)/2;
mergesort(array,left,mid);
mergesort(array,mid+1,right);
merge(array,left,mid,right);
}
}
void merge(int array[], int left, int mid, int right)
{
int i;
int l=0;
int r=mid+1;
int arr_sorted[10];
for(i=0;i<=right;i++){
if((l<=mid) && (r<=right)){
if(array[l]<array[r]){
arr_sorted[i]=array[l];
l++;
}
else {
arr_sorted[i]=array[r];
r++;
}
}
if(l>mid){
arr_sorted[i]=array[r];
r++;
}
if(r>right){
arr_sorted[i]=array[l];
l++;
}
}
for(i=0;i<=right;i++){
array[i]=arr_sorted[i];
}
}
First that is looking strange is why you are passing left parameter to the merge, but iterate from 0 to right; left is not even using in this function.
Some corrections that were needed in the merge function :
void merge(int array[], int left, int mid, int right)
{
int i;
int l=left; //If you are passing left, then it should be used here !!
int r=mid+1;
int arr_sorted[10];
for(i=0;(l<=mid)&&(r<=right);i++){
//Your condition for this loop unnecessarily complicates the rest of the code. This is a better way to go about it
//The loop body is fine
if(array[l]<array[r]){
arr_sorted[i]=array[l];
l++;
}
else {
arr_sorted[i]=array[r];
r++;
}
}
//Now, checking for remaining elements and adding them to the result
//The conditions are simple because of the test condition we used in the previous for loop
if(l>mid){
for(;r<=right;r++,i++) arr_sorted[i]=array[r];
}
if(r>right){
for(;l<=mid;l++,i++) arr_sorted[i]=array[l];
}
}
for(i=0;i<=right;i++){
array[i]=arr_sorted[i];
}
}
Also, as a matter of style, try to keep your forward declarations in one place (more so as the functions are related). Instead of :
void mergesort(int array[], int left, int right)
{
void merge(int array[],int left, int mid, int right);//This line should be moved to the top with the mergesort forward declaration
int mid;
if(left<right){
mid=(left+right)/2;
Try doing :
#include <stdio.h>
#include <stdlib.h>
void mergesort(int array[], int left, int right);
void merge(int array[],int left, int mid, int right); // <--------
This is just a matter of preference, though.
here is the entire working merge sort, you can see the differences, let me know if you have any further questions. I had to change the name because stdlib has mergesort implementation.
#include <stdio.h>
#include <stdlib.h>
int mymergesort(int array[], int left, int right);
int main()
{
int i;
int arr[10];
for(i=10;i>0;i--){
arr[10-i]=i;
}
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
mymergesort(arr,0,9);
puts("\n");
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
return 0;
}
int mymergesort(int array[], int left, int right)
{
void mymerge(int array[],int left, int mid, int right);
int mid;
mid=(left+right)/2;
if(left<right){
mymergesort(array,left,mid);
mymergesort(array,mid+1,right);
mymerge(array,left,mid,right);
}
return 0;
}
void mymerge(int array[], int left, int mid, int right)
{
int i=0;
int l=left;
int r=mid+1;
int arr_sorted[10];
for(i=left;i<=right;){
if((l<=mid) && (r<=right)){
if(array[l]<array[r]){
arr_sorted[i]=array[l];
l++;
i++;
}
else {
arr_sorted[i]=array[r];
r++;
i++;
}
}
if(l>mid){
for(;r<=right;r++){
arr_sorted[i]=array[r];
i++;
}
break;
}
if(r>right){
for(;l<=mid;l++){
arr_sorted[i]=array[l];
i++;
}
break;
}
}
for(i=left;i<=right;i++){
array[i]=arr_sorted[i];
}
}

Quicksort returning unsorted middle/median element?

I am fairly new to programming and have been learning sorting algorithms for a while now.I have implemented Quick sort below in C. It uses median of three partitioning to select the pivot.
The problem with the code is every time I run it, the element that is supposed to be the median/ mid value of the sorted array is unsorted, ie it occurs somewhere else.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
return ;
}
int median3(int a[], int left, int right)//Uses median of three partitioning technique
{
int center = (left + right)/2;
if (a[center] < a[left])
swap(&a[left],&a[center]);
if (a[right] < a[left])
swap(&a[left],&a[right]);
if (a[right]< a[center])
swap(&a[center],&a[right]);
swap(&a[center], &a[right - 1]);//since the largest is already in the right.
return a[right - 1];
}
void quicksort(int a[], int left, int right)
{
if (left < right) {
int pivot = median3(a,left,right);
int i = left;
int j = right - 1;
for ( ; ;) {
while(a[++i]<pivot) {}
while(pivot<a[--j]) {}
if ( i < j)
swap(&a[i],&a[j]);
else
break ;
}
swap(&a[i],& a[right -1]);
quicksort(a,left,i-1);
quicksort(a,i+1,right);
}
return ;
}
int main(int argc, char* argv[])
{
int i;
int a[] = {8,1,4,9,6,3,5,2,7,0};
quicksort(a,0,9);
for ( i = 0 ; i < 10 ; i++)
printf("%d\n",a[i]);
return 0;
}
Watch out for the edge case, where left == right - 1:
void quicksort(int a[], int left, int right)
{
if (left < right) {
int pivot = median3(a,left,right);
if (left == right - 1) return; // only two elements, already sorted by median3()
int i = left;
int j = right - 1;
http://ideone.com/X5Ydx

Resources