Get a series of lower case letters sorted - c

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.

Related

How to adapt this QuickSort (coded in C language) algortim to an array of strings?

I need to sort the content (alphabetically using strcmp() of an array of strings, but I am not allowed to use the function qsort(). With this code I managed to sort numerical values, but I am having a hard time adapting it in order to sort strings.
/* A utility function to swap two elements */
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
void swap_string(char c[63], char d[63]){
char temp[63];
strcpy(temp, c);
strcpy(c, d);
strcpy(d, temp);
}
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition (int arr[], int low, int high)
{
int pivot = arr[high]; /* pivot */
int i = (low - 1); /* Index of smaller element */
for (j = low; j <= high- 1; j++)
{
/* If current element is smaller than the pivot */
if (arr[j] < pivot)
{
i++; /* increment index of smaller element */
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
/* Separately sort elements before */
/* partition and after partition */
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
First, you just need to create a swap function for string, not need for int
void swap(char ** a, char ** b) {
char * t = *a;
*a = *b;
*b = t;
}
Because, you sort an array of string, so using input ** arr instead of arr[]
Here, the partition function:
int partition (char ** arr, int low, int high) {
char * pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high- 1; j++) {
// If current element is smaller than the pivot
if (strcmp(arr[j],pivot) < 0) {
i++; // increment index of smaller element
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
And, quickSort function:
void quickSort(char **arr, int low, int high) {
if (low < high) {
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
Then the main function for test:
int main(){
char *a = "abc";
char *b = "cdf";
swap(&a, &b);
printf("a = %s, b= %s\n", a, b);
char * data[10]={"something2", "something0", "something1", "something6", "something8", "something4", "something5","something7", "something3", "something9"};
quickSort(data, 0, 9);
for(int i = 0; i < 10; i++) {
printf("%s, ", data[i]);
}
return 0;
}
UPDATE:
If you want exactly an array producer[100][63]. You can change the declaration of the function.
In this example, i use an array data[10][63] for testing. In fact, you can use 100 instead of 10.
Swap function:
void swap(char a[63], char b[63]) {
char t[63];
strcpy(t, a);
strcpy(a, b);
strcpy(b, t);
}
Then, partition function:
int partition (char arr[10][63], int low, int high) {
char * pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high- 1; j++) {
// If current element is smaller than the pivot
if (strcmp(arr[j],pivot) < 0) {
i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i + 1], arr[high]);
return (i + 1);
}
Finally, the quickSort function:
void quickSort(char arr[10][63], int low, int high) {
if (low < high) {
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
The main for test:
int main(){
char data[10][63]={"something2", "something0", "something1", "something6", "something8", "something4", "something5","something7", "something3", "something9"};
quickSort(data, 0, 9);
for(int i = 0; i < 10; i++) {
printf("%s, ", data[i]);
}
return 0;
}

Quicksort C - A little different version

The code does run. This is a little different version of quicksort I am working on. I am running into some major issues with it. First off It prints out the first element in the array as n: for example(if you set n = 3, even if you make the first element in the array 1 lets say, it will still print out 3 as the first element). Also when you print out the sorted version it doesn't actually change anything.
Example input with n = 3,
Set values = 8 , 7 , 6
Initial output will equal 3 , 7 , 6
Final output will equal 3 , 7 , 6
(The output SHOULD be 6 , 7 , 8)
I haven't been able to find any code online similar to my code, so this may be something new! Thanks.
//preprocessor directives and header files
#include <stdio.h>
#define MAX_ARRAY_SIZE 50
//function prototypes separated by data types
void print_array( int array[], int n ); // Print out the array values
void swap( int array[], int index1, int index2 ); // Swap two array elements.
void quicksort( int array[], int low, int high ); // Sorting algorithm
int populate_array( int array[] ); // Fill array with values from user.
int partition( int array[], int low, int high ); // Find the partition point (pivot)
//the main function
int main(void)
{
int array[MAX_ARRAY_SIZE];
//set n = to size of user created size of array
int n = populate_array(&array[MAX_ARRAY_SIZE]);
//print the original array to the screen
print_array(&array[MAX_ARRAY_SIZE], n );
//perform the algorithm
quicksort(array, 0, n-1);
printf("The array is now sorted:\n");
print_array(&array[MAX_ARRAY_SIZE], n);
return 0;
}
// *array and array[] are the same...
int populate_array(int array[])
{
int n = -1;
printf("Enter the value of n > ");
scanf("%d", &n);
if(n > MAX_ARRAY_SIZE)
{
printf("%d exceeds the maximum array size. Please try again.\n\n", n);
populate_array( &array[MAX_ARRAY_SIZE]);
}
else if(n < 0)
{
printf("%d is less than zero. Please try again.\n\n", n);
populate_array( &array[MAX_ARRAY_SIZE]);
}
else if(n == 0)
{
printf("%d Array of size 0? Please don't try this, and... Please try again.\n\n", n);
populate_array( &array[MAX_ARRAY_SIZE]);
}
else
{
for(int i = 0; i < n; i++)
scanf("%d", &array[i]);
}
printf("The initial array contains: \n");
return n;
}
void print_array(int array[], int n)
{
for(int i = 0; i < n; i++)
printf("%+5d\n", array[i]);
}
void quicksort(int array[], int low, int high)
{
if (low < high)
{
/* pivot is partitioning index, array[p] is now
at right place */
int pivot = partition(array, low, high);
// Separately sort elements before
// partition and after partition
quicksort(array, low, pivot - 1);
quicksort(array, pivot + 1, high);
}
}
int partition(int array[], int low, int high)
{
int pivot = array[high];
int i = low;
for (int j = low; j <= high- 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (array[j] <= pivot)
{
swap(array, i, j);
i = i +1;
}
}
swap(array, i, high);
return i;
}
void swap(int array[], int index1, int index2)
{
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
Here is a heavily commented answer. I changed the code quite a bit.
This is now a fully functional quicksort array for user input.
The problem I was having before was with the &array[MAX_ARRAY_SIZE]. This needed to be changed to just "array" instead. The &array[MAX_ARRAY_SIZE] was trying to access a memory location past the actual size of the array.
Changing it to just "array" means that it is accessing the first element in the array.(Correct if wrong)
I also changed the populate array function to be a robust do-while loop. And instead of trying to re-call the function inside itself. The do-while loop will only allow you to change the value of 'n'.
/*
Author: Zachary Alberda
*/
//preprocessor directives and header files
#include <stdio.h>
#define MAX_ARRAY_SIZE 50
//function prototypes separated by data types
void print_array( int array[], int n ); // Print out the array values
void swap( int array[], int index1, int index2 ); // Swap two array elements.
void quicksort( int array[], int low, int high ); // Sorting algorithm
int populate_array( int array[] ); // Fill array with values from user.
int partition( int array[], int low, int high ); // Find the partition point (pivot)
//the main function
int main(void)
{
int array[MAX_ARRAY_SIZE]; //set n = to size of user created size of array
int n = populate_array(array); //print the original array to the screen
print_array(array, n ); //print array of size n
quicksort(array, 0, n-1); //perform the algorithm low is 0, high is size of array -1.
printf("The array is now sorted:\n");//Inform user that the array is sorted.
print_array(array, n);//print the sorted array
return 0; // exit without errors.
}
// *array and array[] are the same...
int populate_array(int array[])
{
int n = -1;//initialize variable n(local variable to function populate_array)
printf("Enter the value of n > ");//inform user of what to input
scanf("%d", &n);
/*
CHECK IF N IS VALID
This is a robust do while loop!
1) Performs the if-statements while 'n' is not valid in a do-while loop.
-The reason I do this is because it will cause errors
if the if-statements are individual without the do-while loop.
2)The program will not crash if you try different combinations
of inputs for 'n'. :)
3)Checks if user input is > MAX_ARRAY_SIZE
4)Checks if user input is < 0
5)Checks if user input is == 0
*/
do
{
if(n > MAX_ARRAY_SIZE)
{
printf("%d exceeds the maximum array size. Please try again.\n\n", n);
printf("Enter the value of n > ");
scanf("%d", &n);
}
else if(n < 0)
{
printf("%d is less than zero. Please try again.\n\n", n);
printf("Enter the value of n > ");
scanf("%d", &n);
}
else if(n == 0)
{
printf("%d Array of size 0? Please don't try this, and... Please try again.\n\n", n);
printf("Enter the value of n > ");
scanf("%d", &n);
}
}while(n <= 0 || n > MAX_ARRAY_SIZE);
//scan in array if user input is valid
for(int i = 0; i < n; i++)
scanf("%d", &array[i]);
printf("The initial array contains: \n");//Inform user of initial array
return n;
}
void print_array(int array[], int n)
{
//print array in pre/post order before and after the algorithm.
for(int i = 0; i < n; i++)
printf("%+5d\n", array[i]);
}
void quicksort(int array[], int low, int high)
{
if (low < high)
{
/* pivot is partitioning index, array[pivot] is now
at right place */
int pivot = partition(array, low, high);
// Separately sort elements before
// partition and after partition
quicksort(array, low, pivot - 1);
quicksort(array, pivot + 1, high);
}
}
int partition(int array[], int low, int high)
{
int pivot = array[high];
int i = low;
for (int j = low; j <= high- 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (array[j] <= pivot)
{
swap(array, i, j);
i = i +1;
}
}
swap(array, i, high);
return i;
}
void swap(int array[], int index1, int index2)
{
//swap positions of array index 1 and 2
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}

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

Assignment makes pointer without a cast

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

Resources