sorting arrays in c with pointers - c

I am trying to sort an array from least to greatest using pointers instead of array subscripts. I am not sure where the problem is but when i run this code, the values are returned in the same order that they were entered. The find_largest and swap functions both do exactly what they say. The selection_sort function uses a for loop to sort the numbers from right to left (greatest to smallest, right to left). I have been staring at this for a while now and it looks like it should work fine but like i said, for some reason the numbers are returned in the same order they were entered.
Here is my code:
#include <stdio.h>
#define N 5
void selection_sort(int *a, int n);
int *find_largest(int *a, int n);
void swap(int *p, int *q);
int main(void)
{
int i;
int a[N];
printf("Enter %d numbers to be sorted: ", N);
for (i = 0; i < N; i++)
scanf("%d", (a+i));
selection_sort(a, N);
printf("In sorted order:");
for (i = 0; i < N; i++)
printf(" %d", *(a+i));
printf("\n");
return 0;
}
void selection_sort(int *a, int n)
{
int i = 0;
int *largest;
for(i = 0; i < n; i++){
largest = find_largest(a, n-i);
swap(largest, a+(n-1-i));
}
}
int *find_largest(int *a, int n){
int *p = a;
int *largest = p;
for(p = a; p < a+n-1; p++){
if(*(p+1) > *p){
largest = (p + 1);
}
}
return largest;
}
void swap(int *p, int *q){
int *temp;
temp = p;
p = q;
q = temp;
}

There are two mistakes in your code.
One, logical in the find_largest function:
int *find_largest(int *a, int n){
int *p = a;
int *largest = p;
for(p = a; p < a+n-1; p++){
if(*(p+1) > *largest){ <---- //here you were checking for *(p)
largest = (p + 1);
}
}
return largest;
}
the other is with pointers in swap function:
void swap(int *p, int *q){
int temp;
temp = *p;
*p = *q;
*q = temp;
}

As John Bollinger mentioned in the comments, swap() does not function correctly - all it does is reassign pointers that quickly go out of scope.
Here is a rewrite of that function that does work. Just swap it in and it fits perfectly.
void swap(int *p, int *q){
int temp;
temp = *p;
*p = *q;
*q = temp;
}
Thanks to John Bollinger.

Related

Selection sort algorithm using pointer arithmetic

I need to sort elements of array in ascending order using selection sort algorithm and pointer arithmetic.
That means the following (using pointer arithmetic):
find the minimum element in unsorted array;
swap the found minimum element with the first element
repeat it until the end of array
print sorted array
Code:
#include <stdio.h>
void swap(double **pp, double **qq) {
double *temp = *pp;
*pp = *qq;
*qq = temp;
}
void sortArray(double arr[], int n) {
double *q, *min;
q = min = arr;
while (min > arr + n) {
while (q < arr + n) {
if (*q < *min)
min = q;
q++;
}
min++;
swap(&min, &q);
}
}
void writeSorted(double arr[], int n) {
double *qq = arr;
while (qq < arr + n) {
printf("%g ", *qq);
qq++;
}
}
int main() {
double arr[4] = {2.1, 4.23, 3.67, 1.5};
int n = 4;
sortArray(arr, n);
writeSorted(arr, n);
return 0;
}
This code prints the same unsorted array. Do you know how to fix it?
There is an error about the role of swap: you have to swap the elements, not the corresponding pointers.
Moreover, there is a confusion about definition and role of each pointer.
In particular, it is important to keep trace of the pointer to the start of next iteration.
#include <stdio.h>
void swap(double *pp, double *qq) {
double temp = *pp;
*pp = *qq;
*qq = temp;
}
void sortArray(double arr[], size_t n) {
double *start = arr;
while (start < arr + n) {
double *q = start + 1;
double *min = start;
while (q < arr + n) {
if (*q < *min) min = q;
q++;
}
swap (start, min);
start++;
}
}
void writeArray(double arr[], size_t n) {
double *qq = arr;
while (qq < arr + n) {
printf("%g ", *qq);
qq++;
}
printf ("\n");
}
int main() {
double arr[] = {2.1, 4.23, 3.67, 1.5};
size_t n = sizeof(arr)/sizeof(*arr);
writeArray (arr, n);
sortArray(arr, n);
writeArray(arr, n);
return 0;
}
Besides, I don't know what are exactly your constraints for this exercise. Even by using pointers, some simplifications are possible. For example, for the print function:
void writeArray(double arr[], size_t n) {
while (n--) {
printf("%g ", *arr++);
}
printf ("\n");
}

Calling functions with arrays?

I have some work with this code and i need a swap function that can get a arrays like a[j].
How I need to transport to another function something like this?
#include <stdio.h>
void bubble_sort(int *a, int n) {
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n - i - 1; j++) {
if (a[j] > a[j + 1]) swap(&a[j], &a[j + 1]);
}
}
}
This is the code, so how I can call swap function with a[j]? Do I need to call function like this or?
int swap (int a[],int b[])
int swap (int *a,int *b)
With this second call i am sure that it will work Am i right ? But how can i call this function like the first example?
#define MAX 100
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
return 0;
}
void bubble_sort(int a[], int n) {
int i;
for(i=0;i<n;i++)
{
if(a[i]<a[i+1])
swap(a[i],a[i+1]);
}
return 0;
}
int main()
{
int a[4]={1,2,3,0};
int n=4;
bubble_sort(a,n);
for(int i=0;i<n;i++)
{
printf("%d",a[i]);
}
}
I used that code Segmentation fault (core dumped)
Your function needs to take 2 pointers like this:
void swap(int * const a, int * const b) {
int temp = *a;
*a = *b;
*b = temp;
}
int swap (int a[], int b[]); will also work since in function parameters int* a and int a[] are the same thing. But it is confusing - it implies that the pointer is pointing to an array, while you only want to swap 2 integers.
Here's how you could do it the other way:
void swap(int a[], int b[]) {
int temp = *a;
*a = *b;
*b = temp;
}

[C Programming]Vectors & Pointers

I don't have idea where is the problem but the latest pointer(vector) have some troubles.
First value it's ok (V[0]+T[0]) , S[1] it's always 0 and third value it's random.
#include <stdio.h>
#include <stdlib.h>
int citire_vector(int n, int *V);
void afisare_vector(int n, int *V);
int produs_scalar(int n, int *V, int *T);
int suma_vectori(int n, int *V, int *T);
int main(void)
{
int n, *X, *Y, ps, *S;
printf("n = ");
scanf("%d",&n);
X = (int*) malloc(n*sizeof(int));
Y = (int*) malloc(n*sizeof(int));
citire_vector(n,X);
citire_vector(n,Y);
afisare_vector(n,X);
afisare_vector(n,Y);
ps = produs_scalar(n,X,Y);
printf("Produsul scalar = %d\n",ps);
S = (int*) malloc(n*sizeof(int));
*S= suma_vectori(n,X,Y);
afisare_vector(n,S);
}
int citire_vector(int n, int *V)
{
int i;
for(i=0;i<n;i++)
scanf("%d",V+i);
return *V;
}
void afisare_vector(int n, int *V)
{
int i;
printf("Valorile vectorului sunt:\n");
for(i=0;i<n;i++)
printf("%d ",*(V+i));
printf("\n");
}
int produs_scalar(int n, int *V, int *T)
{
int i, ps = 0;
for(i = 0;i<n;i++)
ps += (*(V+i))*(*(T+i));
return ps;
}
int suma_vectori(int n, int *V, int *T)
{
int i, *U;
for(i=0;i<n;i++)
{
*(U+i )= *(V+i);
}
return *U;
}
Your suma_vectori and its usage are incorrect.
Pointer U inside suma_vectori is uninitialized, causing undefined behavior on assignment
Assignment *S= suma_vectori(n,X,Y) has no effect beyond the initial element of S
To fix this problem, change suma_vectori to return int*, move malloc of the result inside the function, remove malloc for S, and assign S the result of the suma_vectori call:
int *suma_vectori(int n, int *V, int *T); // forward declaration
int *suma_vectori(int n, int *V, int *T) { // Implementation
int *U = malloc(n*sizeof(int)); // do not cast malloc
for(int i=0;i<n;i++) {
U[i] = V[i] + T[i];
}
return U;
}
// call
S= suma_vectori(n,X,Y);
// Don't forget to free malloc-ed memory
free(X);
free(Y);
free(S);
You have to allocate memory to U in suma_vectori function
as it is picking garbage value

C - How to make function return a pointer?

This function should return a pointer to the first occurrence of the largest int in an array without using the index operator. It can find and print the largest int, but how do I make it return a pointer? And how do I test if it was successful?
int *arr_first_max(const int *a, size_t n) {
const int *k;
int largest = 0;
for (k = a; *k != '\0'; k++) {
if (*k > largest) {
largest = *k;
}
}
printf("%d\n", largest);
return &largest;
}
Edit: size_t n is supposed to be used but I'm not sure how to include it.
And another answer assuming:
n is length of array a (in terms of elements, not bytes)
You want to iterate through the whole array a
Then code is:
const int *arr_first_max(const int *a, size_t n) {
const int *largest = a;
while(n--) {
if(*a>*largest)
largest = a;
a++;
}
printf("%d\n", *largest);
return largest;
}
In all functions n is assumed to be >0.
Just keep your logic, but instead of storing the max, store the index to the max, in order to return a pointer to the array at that index.
int *arr_first_max(const int *a, size_t n) {
int i,l;
for (l=i=0 ; i<n ; i++)
if (a[i] > a[l]) l = i;
return a+l;
}
Edit Pointer only version (based on comments) which does n-1 iterations
const int *arr_first_max(const int *a, size_t n) {
const int *most;
for (most=a++ ; --n ; a++) if (*a > *most) most = a;
return most;
}
And since I misread the question, a recursive bonus!
const int *arr_first_max_r(const int *most, const int *a, size_t n) {
if (*a > *most) most = a;
return --n ? arr_first_max_r(most, ++a, n) : most;
}
to be called like this
printf("Biggest int is : %d\n", *arr_first_max_r(a, a, n));
This works. You detect the largest number like you did then run the same loop again to see where the number is then return that address. I also changed some data types from int to const int and I removed the 2nd parameter because you're checking for null characters.
#include <stdio.h>
#include <stdlib.h>
const int *arr_first_max(const int *a) {
const int *k;
int largest=0;
for (k = a; *k != '\0'; k++) {
if (*k > largest){
largest = *k;
}
}
for (k = a; *k != '\0'; k++) {
if (*k == largest){
return k;
}
}
}
int main(){
int nums[6]={7,2,1,5,4,6};
const int* y=arr_first_max(nums);
printf("%d\n", *y);
}
Assuming
the function's signature is correct and complete (arr_first_max alludes that you search in an array for the first max element)
and thus int* a is the pointer to the first element (i.e. equivalent to int a[] in a signature); I'll leave the const specifier in this case, though I think you could omit/discard it if the exercise permits that
size_t n is the size of the array or, in other words, the number of elements in the array
you want to return a pointer to largest element in the array without using the subscript [] operator
then this would be a solution
int *arr_first_max(const int *a, size_t n) {
int *largest, *k;
for (largest = k = a; (k - a) < n; k++)
if (*k > *largest)
largest = k;
return largest;
}
That is because I quote from The C Programming Language:
Pointer subtraction is also valid: if p and q point to elements of
the same array, and p<q, then q-p+1 is the number of elements from
p to q inclusive.
i won't guess what size_t n is for
int *arr_first_max( int *a, size_t n) {
int *largest = a;
while(*a){
a++;
if(*a>*largest) largest=a;
}
return largest;
}

C Program, function sorting through pointers

This program is supposed to take an array, and sort it from lowest to highest value. My program won't sort any values though. I believe the error is in the selectionSort. The values i and j are present in the function, I printed them out inside the function but they are not passed into the swap function. I tried making i and j pointers but it didn't work. I just have no clue on what to do next. Any help would be appreciated.
#include <stdio.h>
#define N 5
void selectionSort(int *a, int n);
int *findLargest(int *a, int n);
void swap(int *p, int *q);
int main(void)
{
int i;
int a[N];
printf("Enter %d numbers: ", N);
for (i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
selectionSort(a, N);
printf("In sorted order:");
for (i = 0; i < N; i++) {
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
void selectionSort(int *a, int n)
{
int *p = a;
int i;
int j;
if (n == 1) {
return;
}
i = *(p+n-1);
j = *findLargest(a, n);
swap(&i, &j);
selectionSort(a, n - 1);
}
int *findLargest(int *a, int n)
{
int *p;
int *p_max = a;
for(p = a + 1; p < a + n - 1; p++) {
if ( *p > *p_max)
p_max = p;
}
return p_max;
}
void swap(int *p, int *q)
{
int temp = *(p-1);
*(p-1) = *q;
*q = temp;
}
The problem is in your call of swap: you swap the content of two local variables
int i;
int j;
... // Some other code, then
swap(&i, &j);
This has no effect on the original array. You should be passing p+n-1 and findLargest(a, n) directly, or store their results in pointers, not in ints:
swap(p+n-1, findLargest(a, n));
In addition, your swap is broken: rather than swapping the content of two pointers, it assumes that p points one element past the target location. This is a bad assumption to make in a general-purpose function, such as swap, and it also leads to undefined behavior in your program.
void swap(int *p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}

Resources