Assignment makes pointer without a cast - c

I am editing a quick sort code so that the values of low, high, and middle point to an array element instead of integers.
This is my code:
#include <stdio.h>
#define N 10
void quicksort(int a[], int *low, int *high);
int split(int a[], int *low, int *high);
int main(void)
{
int a[N], i;
printf("Enter %d numbers to be sorted: ", N);
for (i=0; i<N; i++)
scanf("%d", &a[i]);
quicksort(a, &a[0], &a[N-1]);
printf("In sorted order: ");
for (i=0; i<N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
void quicksort(int a[], int *low, int *high)
{
int *middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
int split(int a[], int *low, int *high)
{
int part_element = *low;
for (;;) {
while (low < high && part_element <= *high)
high--;
if (low >= high) break;
*low++ = *high;
while (low < high && *low <= part_element)
low++;
if (low >= high) break;
*high-- = *low;
}
*high = part_element;
return *high;
}
I'm getting the error message:
qs.c:32:12: warning: assignment makes pointer from integer without a cast [enabled by default]
middle = split(a, low, high);
^
Can someone help me with this? Still a beginner at programming. All types of help are appreciated.

The problem is in this statement.
middle = split(a, low, high);
because middle is a pointer variable whereas split is a function which returns integer value not a pointer to an integer.
You are assigning integer value to a pointer variable middle .
You are not allowed to do that. :)
May be this will help you.

Change 'split()' to return an 'int *' instead of 'int'.
Change the last line of the 'split()' function from:
return *high;
to
return high;
Perhaps this would work better:
#include <stdio.h>
#define N 10
void quicksort(int a[], int *low, int *high);
int *split(int a[], int *low, int *high);
int main(void)
{
int a[N], i;
printf("Enter %d numbers to be sorted: ", N);
for (i=0; i<N; i++)
scanf("%d", &a[i]);
quicksort(a, &a[0], &a[N-1]);
printf("In sorted order: ");
for (i=0; i<N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
void quicksort(int a[], int *low, int *high)
{
int *middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
int *split(int a[], int *low, int *high)
{
int part_element = *low;
for (;;) {
while (low < high && part_element <= *high)
high--;
if (low >= high) break;
*low++ = *high;
while (low < high && *low <= part_element)
low++;
if (low >= high) break;
*high-- = *low;
}
*high = part_element;
return high;
}

Related

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

Recursive binary search function missing something? (C)

I'm trying to make a function that does a binary search on a sorted array. I've checked everything, and everything works correctly, except one thing:
If I don't put a return statement in the end of the function, not surrounded by If's, It won't build my program. If I put 'return 0', it would always return 0, no matter what. If I'll do the same with 1, it would always return 1, and I can't see where is my problem. Would love some help.
#include <stdio.h>
#define N 4
int search_matrix(int a[N][N], int x);
int binsearch(int a[], int x, int low, int high);
int main(){
int a[N][N];
printf("Please Enter Matrix : \n");
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
scanf("%d",&a[i][j]);
}//forj
}//fori
printf("Please enter x : \n");
int x;
scanf("%d",&x);
printf("%d\n",search_matrix(a,x));
return 0;
}
int search_matrix(int a[N][N], int x){
if(x>a[0][N-1]||x<a[N-1][0])
return 0;
int savedIndex=0;
for(int i=0;i<N;i++){
if(x>a[i][0]){
savedIndex=i;
break;
}
}//for
return(binsearch(a[savedIndex],x,0,N));
}//search_matrix
//------- THE PROBLEMATIC FUNCTION! ---------
int binsearch(int a[], int x, int low, int high) {
int mid;
if (low > high)
return 0;
mid = (low + high) / 2;
if (x == a[mid]) {
return 1;
} else if (x < a[mid]) {
binsearch(a, x, low, mid - 1);
} else {
binsearch(a, x, mid + 1, high);
}
}
Check it out:
#include<stdio.h>
#define N 4
int search_matrix(int a[N][N], int x);
int binsearch(int a[], int x, int low, int high);
int main(){
int a[N][N], i, j;
printf("Please Enter Matrix : \n");
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%d",&a[i][j]);
}//forj
}//fori
printf("Please enter x : \n");
int x;
scanf("%d",&x);
printf("%d\n",search_matrix(a,x));
return 0;
}
int search_matrix(int a[N][N], int x){
if(x>a[0][N-1]||x<a[N-1][0])
return 0;
int savedIndex=0, i;
for(i=0;i<N;i++){
if(x>a[i][0]){
savedIndex=i;
break;
}
}//for
return(binsearch(a[savedIndex],x,0,N));
}//search_matrix
//------- THE PROBLEMATIC FUNCTION! ---------
int binsearch(int a[], int x, int low, int high) {
int mid;
if (low > high)
return 0;
mid = (low + high) / 2;
if (x == a[mid]) {
return 1;
} else if (x < a[mid]) {
binsearch(a, x, low, mid - 1);
} else {
binsearch(a, x, mid + 1, high);
}
}

Quicksort giving me two different set of numbers

Hi i've written a quick program testing the quicksort to see if i understand it fully but it seems like sorting different array. I assume i need to type of pointer? It also seems like the sorted array randomising quite a bit of 0's. Is there something wrong with the code?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 150
void quickSort(int array[], int low, int high); // sorting algorithm
int split(int array[], int low, int high); // spit the array
int main(void)
{
int array[MAX];
int i;
srand((unsigned)time(NULL));
for (i=0;i<MAX;i++)
{
array[i] = rand()%MAX;
printf("#%d:[%d]\n", i+1, array[i]);
quickSort(array, 0, MAX-1);
}
printf("The sorted order:\n");
for(i=0;i<MAX;i++)
{
printf("#%d:[%d]\n", i+1,array[i]);
}
return 0;
}
// function
void quickSort(int array[], int low, int high) // sorting algorithm
{
int middle;
if (low >= high)
{
return;
}
middle = split(array, low, high);
quickSort(array, low, middle-1);
quickSort(array, middle+1, high);
}
int split(int array[], int low, int high)
{
int partElement = array[low];
for(;;)
{
while (low < high && partElement <= array[high])
{
high--;
}
if (low>= high)
{
break;
}
array[low++]=array[high];
while (low < high && array[low] <= partElement)
{
low++;
}
if (low >= high)
{
break;
}
array[high--] = array[low];
}
array[high] = partElement;
return high;
}

Get a series of lower case letters sorted

The algorithm works fine with integers but since I converted them into char, it has been printing null for the output:
/* sort a series of lower case letters using quicksort algorithm. */
#include <stdio.h>
#define N 10
// since c gets the ascii code when returning an int for a char variable.
char quicksort(char a[], char low, char high);
char split(char a[], char low, char high);
int a[N];
int main(void)
{
int i;
printf("Enter letters to be sorted: ");
for (i = 0; i < N; i++)
scanf("%d", &a[i]);
quicksort(a, 0, N - 1);
printf("In sorted order: ");
for (i = 0; i < N; i++)
printf("%s ", a[i]);
printf("\n");
return 0;
}
char quicksort(char a[], char low, char high)
{
int middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
char split(char a[], char low, char high)
{
char part_element = a[low];
for (;;) {
while (low < high && part_element <= a[high])
high--;
if (low >= high) break;
a[low++] = a[high];
while (low < high && a[low] <= part_element)
low++;
if (low >= high) break;
a[high--] = a[low];
}
a[high] = part_element;
return high;
}
Three issues:
a is declared as an array of int, but all your functions handle an array of char. This means they won't iterate through the array correctly. Change it to char a[N].
To read a character, use the %c format specifier to scanf.
To print a character, use the %c format specifier to printf.
The revised code still doesnt work and i cant seem to find the bug.
Your problems appear to be with main() pretty much along the lines that other folks have suggested with respect to using char oriented data instead of int. There are some non fatal questionable choice issues like using char datatypes for array indexes; quicksort() is declared to return char but returns nothing; and so forth. Below is a rework of your code, mostly for style, incorporating various folks suggestions:
/* sort a series of letters using quicksort algorithm. */
#include <stdio.h>
#define N (10)
void quicksort(char a[], int low, int high);
int split(char a[], int low, int high);
int main(void)
{
char a[N];
printf("Enter letters to be sorted: ");
for (int i = 0; i < N; i++) {
scanf("%c", &a[i]);
}
quicksort(a, 0, N - 1);
printf("In sorted order: ");
for (int i = 0; i < N; i++) {
printf("%c ", a[i]);
}
printf("\n");
return 0;
}
void quicksort(char a[], int low, int high)
{
if (low < high) {
int middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
}
int split(char a[], int low, int high)
{
char part_element = a[low];
for (;;) {
while (low < high && part_element <= a[high]) {
high--;
}
if (low >= high) {
break;
}
a[low++] = a[high];
while (low < high && a[low] <= part_element) {
low++;
}
if (low >= high) {
break;
}
a[high--] = a[low];
}
a[high] = part_element;
return high;
}
Does it not do everything it's supposed to?
EXAMPLE
> ./a.out
Enter letters to be sorted: aadircslne
In sorted order: a a c d e i l n r s
>
scanf requires a %c format specifier. Your scanf should change to
scanf("%c", &a[i]);
As a result, you should redeclare the a array to char, not int.

Segmentation error but I don't know why

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_SIZE 100
I am trying to quicksort an array of 2D points based upon their distance from the origin but my code hits a Seg fault after the first scanf.
typedef struct point{
double x;
double y;
double dist;
} point;
void sortpoints(point arr[], int low, int high);
void printpoints(point arr[], int n);
Sortpoints is just a manipulation of a quicksort in ordering an array of Point structs depending on the value of Point.dist
void sortpoints(point arr[], int low, int high){
int piv, i, j;
piv = low;
i = low;
j = high;
point box;
if(low < high){
while(i<j){
while((arr[i].dist)<=(arr[piv].dist) && i<= high)
i++;
}
while((arr[j].dist) > (arr[piv].dist) && j>= low)
j--;
}
if(i<j){
box = arr[i];
arr[i] = arr[j];
arr[j] = box;
}
box = arr[j];
arr[j] = arr[piv];
arr[piv] = box;
sortpoints(arr, low, j-1);
sortpoints(arr, j+1, high);
}
Printpoints just prints the points in order of their distances from the origin
void printpoints(point arr[], int n){
int i; for(i = 0; i <= n; i++){
printf("(%.2lf, %.2lf)\n", arr[i].x, arr[i].y);
}
}
The user enters the number of points and value of the points in the form (point.x, point.y)
int main(){
point pointa;
point pointarray[MAX_SIZE];
int n=0;
printf("how many points would you like to enter?\n");
scanf("%d", &n);
if(n<MAX_SIZE){
int i;
for(i=0; i<n ; i++){
scanf("(%lf,%lf)", &pointa.x, &pointa.y);
pointa.dist = sqrt(pointa.x*pointa.x + pointa.y*pointa.y);
pointarray[i] = pointa;
}
sortpoints(pointarray, 0, n-1);
printpoints(pointarray, n);}
else{
printf("sorry, not a valid array size\n");
}
return 0;
}
I've got stack overflow.
Your program calls function sortpoints, and calls itself too (sortpoints calls sortpoints). But i cant see where sortpoints must stop!
As a result, j-1 goes under null, and arr[j] is not valid at all.
When I changed this line:
scanf("(%lf,%lf)", &pointa.x, &pointa.y);
To this:
scanf("%lf,%lf", &pointa.x, &pointa.y);
The point values were actually being read in, with the parens there nothing gets read in, I don't see anything in the documentation on scanf about this though, is anyone familiar with this?
You sorting code seems to go into infinite recursion and cause a stack overflow however.
Your issue is with your braces. I have reformatted your sortpoints function slightly so it is clearer where each basic block actually is.
void sortpoints(point arr[], int low, int high){
int piv, i, j;
piv = low;
i = low;
j = high;
point box;
if(low < high){
while(i<j){
while((arr[i].dist)<=(arr[piv].dist) && i<= high)
i++;
}
while((arr[j].dist) > (arr[piv].dist) && j>= low)
j--;
}
if(i<j){
box = arr[i];
arr[i] = arr[j];
arr[j] = box;
}
box = arr[j];
arr[j] = arr[piv];
arr[piv] = box;
sortpoints(arr, low, j-1);
sortpoints(arr, j+1, high);
}
It should be evident now that your segfault is the result of accidental infinite recursion. This is a good argument for using { } for your loops, even with a single statement.

Resources