Quicksort implementation in C language - c

I am trying to implement quicksort in c language but the sorting is not happening as intended.
#include <stdio.h>
void quickSort(int arr[], int length);
void qSrtRec(int arr[], int low, int high);
void swap(int* x, int* y);
int partition(int arr[], int low, int high);
int main() {
int arr[] = { 5,3,7,0,1,4,8,9,6,2 }; // test array
quickSort(arr, sizeof(arr) / sizeof(arr[0]));
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
printf("%d, ", arr[i]);
printf("\n");
return 0;
}
void swap(int* x, int* y) {
*x += *y;
*y = *x - *y;
*x -= *y;
}
void quickSort(int arr[], int length) {
qSrtRec(arr, 0, length - 1);
}
void qSrtRec(int arr[], int low, int high) {
if (low < high) {
int pivot = partition(arr, low, high);
qSrtRec(arr, low, pivot - 1);
qSrtRec(arr, pivot + 1, high);
}
}
int partition(int arr[], int low, int high) {
int i = low, pivotValue = arr[high];
for (int j = low; j < high; j++)
if (arr[j] <= pivotValue) {
swap(&arr[i], &arr[j]);
i++;
}
swap(&arr[high], &arr[i]);
return i;
}
Compared to the test array i am getting the output as 0, 0, 2, 0, 0, 0, 0, 7, 0, 0. Swap fuction works correctly but i am not sure about the partition function.

The Swap function is the problem. It will work if you replace it with:
void swap(int* x, int* y) {
int t = *y;
*y = *x;
*x = t;
}
The program now outputs 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

Related

Swap is not done between 2 integers in array in C language

I'm implementing Quick Sort Algorithm in C language, in which at only one particular interchange of 2 values arr[i] and pivot is not being done properly, else all the swapping is done accurately, I have debugged too and tried to understand what is the problem/mistake, maybe it is a logical error.
Here's the code:
#include <stdio.h>
void printArr(int arr[], int n)
{
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void quickSort(int arr[], int low, int high)
{
int pvt = arr[high];
int i = low;
int j = high;
while (i < j)
{
while (pvt > arr[i])
i++;
while (pvt <= arr[j])
j--;
if (i < j)
swap(&arr[i], &arr[j]);
}
swap(&arr[i], &pvt);
printArr(arr, high + 1);
}
void main()
{
int arr[] = {10, 16, 8, 12, 15, 6, 3, 9, 5};
int n = sizeof(arr) / sizeof(arr[0]);
quickSort(arr, 0, n - 1);
}
Just after 2-3 minutes, a friend of mine helped me out, that the pivot is not present in the array so with what I'm swapping it with arr[i]? Instead I can swap 2 values for the same result, arr[i] and arr[high]. Got my mistake :P

Quicksort with pointers causing segfault

I'm trying to take the standard quicksort algorithm and slightly modify it by taking the partition function and making it so that instead of taking the entire array, a low index and a high index, it takes in a pointer to the low'th element as well as how many elements I want to partition. However, I'm getting a segmentation fault and I can't figure it out. Thanks for the help.
#include <stdio.h>
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
int partition(int *array, int high) {
int pivot = array[high];
int i = 0;
for (int j = 0; j < high; j++) {
if (array[j] <= pivot) {
swap(&array[i++], &array[j]);
}
}
swap(&array[i], &array[high]);
return i;
}
void quickSort(int *array, int low, int high) {
if (low < high) {
int pi = partition(array + low, high - low);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
void printArray(int array[], int size) {
for (int i = 0; i < size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}
int main() {
int data[] = {8, 7, 2, 1, 0, 9, 6};
int n = sizeof(data) / sizeof(data[0]);
printf("Unsorted Array\n");
printArray(data, n);
// perform quicksort on data
quickSort(data, 0, n - 1);
printf("Sorted array in ascending order: \n");
printArray(data, n);
}
Given the following in your code:
int pi = partition(array + low, high - low);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
You're partitioning using a pointer-adjusted base (array+low), and segment pure length (high-low). That's fine if that is how your partition implementation works (most do). But you need to remember the resulting pivot location, pi, will be based on a position in that segment; not in the overall array. You need to adjust for that when recursing by putting back the original offset from whence that partition was configured:
int pi = partition(array + low, high - low);
quickSort(array, low, low + pi - 1); // <== LOOK
quickSort(array, low + pi + 1, high); // <== HERE
That change alone should get your implementation running. There are other ways to do this, and I'll update this answer with a couple of them when/if I find the time.
Alternate version of a pointer based quicksort using Hoare partition scheme:
void QuickSort(int *lo, int *hi)
{
int *i, *j;
int p, t;
if(lo >= hi)
return;
p = *(lo + (hi-lo)/2);
i = lo - 1;
j = hi + 1;
while (1){
while (*(++i) < p);
while (*(--j) > p);
if (i >= j)
break;
t = *i;
*i = *j;
*j = t;
}
QuickSort(lo, j);
QuickSort(j+1, hi);
}

What does segmentation fault (core dumped) mean? (quicksort code)

I am writing a quicksort function and am getting a segmentation fault error. I'm not sure why this is. Any help is appreciated. Here's my code. I know the error means that I'm trying to access memory that doesn't exist but I'm not sure where exactly the mistake is.
#include <stdio.h>
void swap(int arr[], int i, int j){
int tmp;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
int partition(int arr[], int first, int last){
int pivot = arr[last];
while(first <= last){
while(arr[first] < pivot){
first++;
}
while(arr[last] > pivot){
last--;
}
if(first <= last){
swap(arr, arr[first], arr[last]);
first++;
last--;
}
}
}
void quickSortR(int arr[], int first, int last){
if(last <= first) return;
int mid = partition(arr, first, last);
quickSortR(arr, first, mid-1);
quickSortR(arr, mid+1, last);
}
void main() {
int arr[14] = {488888, 3, 5, 0, 23, 12124, 6, 7, 2, 1121, 0, 92, 5, 8};
quickSortR(arr, 0, 13);
for (int i = 0; i<14; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
}
This function return int but you don't return anything:
int partition(int arr[], int first, int last){
so it make the mid is undefined state and make arr[mid-1] or arr[mid] is out of range
int mid = partition(arr, first, last);
Please return the value from function partition.
The segmentation fault is in the following lines:
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
You are sending array elements to swap( as i and j) and using them as indices, obviously these lines will cause seg fault as these addresses may be out of bounds and system reserved.
As told by #Loc the 'partition' function should return the mid value's index, also you forgot to swap the pivot. There are some other minor corrections. I have included the corrected code:
#include <stdio.h>
void swap(int arr[], int i, int j){
int tmp;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
int partition(int arr[], int first, int last){
int pivot = arr[last];
int p=last;
last--;
while(first <= last){
while(arr[first] < pivot){
first++;
}
while(arr[last] > pivot){
last--;
}
if(first <= last){
swap(arr, first, last);
first++;
last--;
}
}
swap(arr, first, p);
return first;
}
void quickSortR(int arr[], int first, int last){
if(last <= first) return;
int mid = partition(arr, first, last);
quickSortR(arr, first, mid-1);
quickSortR(arr, mid+1, last);
}
void main() {
int arr[14] = {488888, 3, 5, 0, 23, 12124, 6, 7, 2, 1121, 0, 92, 5, 8};
int i;
quickSortR(arr, 0, 13);
for (i = 0; i<14; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
}

merge_sort works and not works in some condition(input number)

I have this c code for merge sort.
The code works well when N<=4 but does not when N>4.
If I put in 4 for N and enter 4 numbers, the result shows as it should.
However, when I put in 6 and enter 6 numbers, the program stops for few seconds and puts out nothing as result.
What can I do to make this code work for all occasions(N
#include <stdio.h>
#include <stdlib.h>
#define MAX 100000
void Merge(int* arr, int p, int q, int r);
void MergeSort(int *arr,int p, int r);
int main(void)
{
int N, i;
int *arr ;
scanf("%d", &N);
if ((N>MAX) || (N<1))
return -1;
arr = (int*)malloc(sizeof(int)*N);
for (i = 0; i<N; i++)
scanf("%d", &arr[i]);
MergeSort(arr, 0, N - 1);
for (i = 0; i<N; i++)
printf("%d\n", arr[i]);
free(arr);
}
void Merge(int *arr, int left, int mid, int right)
{
int i,i1,i2;
int b[right-left+1];
for(i=left, i1=left, i2=mid+1;i<=right && i1<=mid && i2<=right;i++ ){
if(arr[i1]>arr[i2])
b[i]=arr[i1++];
else
b[i]=arr[i2++];
}
for(i; i<=right;i++){
if(i1<=mid)
b[i]=arr[i1++];
if(i2<=right)
b[i]=arr[i2++];
}
for(i=left;i<=right;i++)
arr[i] = b[i];
}
void MergeSort(int *arr, int left, int right)
{
int mid;
if (left<right){
mid = (left + right) / 2;
MergeSort(arr, left, mid);
MergeSort(arr, mid + 1, right);
Merge(arr, left, mid, right);
}
else
return;
}

Expression must have arithmetic type

While trying to write a code to find the intersection of two arrays,I came across a problem. I can't seem to modify a pointer inside a function.
Inside my find_intersection I get the error while doing the realloc function,compiler states that "counter" has no arithmetic value.
Any explanation on what went wrong here?
#include <stdio.h>
#include <stdlib.h>
int quick_sort(int*, int, int);
void swap(int*, int*);
int partition(int *, int, int);
int input_array_dyn(int*n);
int *find_intersection(int*, int*, int*, int, int,int *);
main()
{
int size1, size2, *counter, i=0;
int *arr1 = input_array_dyn(&size1);
int *arr2 = input_array_dyn(&size2);
quick_sort(arr1, 0, size1 - 1);
quick_sort(arr2, 0, size2 - 1);
int *arr3 = (int*)calloc(size2, sizeof(int));
arr3= find_intersection(arr1, arr2, arr3, size1, size2, &counter);
printf("The size of the new array is:%d\n", counter);
while (i < counter)
{
printf("%d\n", arr3[i]);
i++;
}
free(arr1);
free(arr2);
free(arr3);
}
int *find_intersection(int *arr1, int *arr2, int *arr3, int SA, int SB, int *counter)
{
int i = 0, j = 0, n = 0;
*counter = 0;
while (i < SA &&j < SB)
{
if (arr1[i] < arr2[j])
i++;
else if (arr2[j] < arr1[i])
j++;
else
{
arr3[n] = arr1[i];
i++;
n++;
j++;
}
}
counter = n;
arr3 = (int*)realloc(arr3, counter*sizeof(int));/*error here*/
return arr3;
}
int input_array_dyn(int*n)
{
int i;
int *a;
printf("Enter the size of the array:\n");
scanf("%d", n);
a = (int*)calloc(*n, sizeof(double));
assert(a);
printf("Enter the array elements:%d.\n", *n);
for (i = 0; i < *n; i++)
scanf("%d", a + i);
return a;
}
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
int partition(int *arr, int low, int high)
{
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
if (arr[j] <= pivot)
{
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
int quick_sort(int *arr, int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quick_sort(arr, low, pi - 1);
quick_sort(arr, pi + 1, high);
}
}
In find_intersection() counter is a pointer to an int. To change it's value you need to use *counter instead of counter.
return arr3; attempts to return a pointer to int while function is declared to return just int. counter is a pointer to an int while you are using it as an regular int setting to 0 and so on.

Resources