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
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
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);
}
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]);
}
}
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;
}
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.