0

I want to sort values inside my priority queue that have the same priority. Everything is loaded from a simple .txt file. I already sorted all priorities, but now I would like to sort values that share the same priority.

My code is relatively simple. It has push and pop functions that, you've guessed it, push and pop haha.

Function ispis is made for printing. Also I know that declaring a dummy node is not a good idea, but they taught us that way at the uni so I got comfortable with it.

Here's an example how I would like to sort my elements:

E.g.

10 1 
2 1
3 1

to

2 1 
3 1
10 1 

My code:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct cvor* Red;
struct cvor {
    int el, pr;
    Red next;
};
void push(Red R, int b, int p);
void print(Red R);
void pop(Red R);

int main() {
    FILE* dat;
    int br, pr;
    struct cvor Head;
    Head.next = NULL;
    dat = fopen("redsp.txt", "r");

    if (!dat) {
        printf("No file!\n");
    }
        
    while (fscanf(dat, "%d %d", &br, &pr) != EOF) {
        push(&Head, br, pr);
    }
        
    printf("Printing:\n");
    print(Head.next);

    /*printf("\n\n\n");
    printf("poppin:D\n");
    for (int i = 0; i < 14;i++) {
        pop(&Head);
        printf("\n\n\n");
        print(Head.next);
    }*/

    fclose(dat);    
}

void push(Red R, int b, int p) {
    Red q;
    q = (Red)malloc(sizeof(struct cvor));

    q->el = b;
    q->pr = p;

    /*if (q->pr >p) {
        q->next = R;
        R = q;
    }*/

        while (R->next != NULL && R->next->pr < p)
        {   
            R = R->next;
        }
            
        q->next = R->next;
        R->next = q;    
    
}

void pop(Red R) {
    Red temp, pre;
    temp = R->next;
    pre = NULL;

    while (temp && temp->next) {
        pre = temp;
        temp = temp->next;
    }
    if (pre) {
        free(pre->next);
        pre->next = NULL;
    }

}


void print(Red R) {
    while (R != NULL)
    {
        printf("%d %d\n", R->el, R->pr);
        R = R->next;
    }
}
Bodo
  • 9,287
  • 1
  • 13
  • 29
Jack Jones
  • 57
  • 6
  • The code would be easier to understand if you would use the same name for corresponding variables, function arguments and structure fields. I suggest to [edit] your question and extend the example input with different values in both columns and show the current result and the expected result. I guess your question is basically how to sort data based on comparing two values, i.e. how to replace `while (R->next != NULL && R->next->pr < p)` to compare both elements. – Bodo Feb 12 '21 at 15:45
  • @Bodo I edited my code. Well yeah, you could call it that. Is there a way to make that algorithm? – Jack Jones Feb 12 '21 at 15:51

1 Answers1

2

As I understand your problem, the question is how to compare data based on two values.

The line

    while (R->next != NULL && R->next->pr < p)

checks for the end of the list and compares one field of the node structure.

To make the code more clear I suggest to replace the comparison with a function call.

void push(Red R, int b, int p) {
    Red q;
    q = (Red)malloc(sizeof(struct cvor));

    q->el = b;
    q->pr = p;

    while (R->next != NULL && compare_nodes(R->next, q) < 0)
    {   
        R = R->next;
    }
            
    q->next = R->next;
    R->next = q;    
}

Your current comparison can be implemented as

/**
 * Compare two nodes.
 *
 * This implementation compares only the pr fields.
 *
 * @param a Pointer to node A.
 * @param b Pointer to node B.
 *
 * @retval <0 if A < B
 * @retval 0  if A == B
 * @retval >0 if A > B
 */
int compare_nodes(const struct cvor *a, const struct cvor *b) {
    /* here only the "pr" element is compared */
    int retval = a->pr - b->pr;
    return retval;
}

You can extend the function to compare other structure fields if the comparison result for the first field is "equal".

int compare_nodes(const struct cvor *a, const struct cvor *b) {
    /* compare pr field first */
    int retval = a->pr - b->pr;
    /* compare el field if necessary */
    if (retval == 0) retval = a->el - b->el;
    return retval;
}

Note that in production code the functions should make sure that the arguments are not NULL pointers instead of relying on the caller.

Bodo
  • 9,287
  • 1
  • 13
  • 29
  • Thank you for your time, but that did not fix my problem unfortunatlely. – Jack Jones Feb 12 '21 at 16:35
  • This is what I have inside my file: 1 2 3 4 5 2 4 3 9 1 4 1 1 1 3 2 5 1 6 2 10 1 2 2 3 2 So you can put that inside your compiler and see it yourself. – Jack Jones Feb 12 '21 at 16:36
  • 1
    @JackJones Please edit your question to show your real input and format it as a code block. Show the output you get with your program and the expected output you want to get. – Bodo Feb 12 '21 at 16:40
  • 1
    There is a typo in my code: `if (retval = 0)` must be `if (retval == 0)`. Your compiler should have displayed a warning about this. – Bodo Feb 12 '21 at 16:50
  • Instead of "that did not fix my problem" you should explain what's wrong with the solution. In this case it would be that the output is the input in reverse order, not sorted in any way. – Bodo Feb 12 '21 at 16:54
  • Please accept my apology sir. Thank you for your time and help. The code fixed my problem. It did not work at first because of that typo and my compiler did not me warn about this. Thank you a lot! – Jack Jones Feb 15 '21 at 15:34
  • 1
    @JackJones If your compiler did not show a warning, you might have to enable all warnings. See https://stackoverflow.com/q/57842756/10622916 – Bodo Feb 15 '21 at 15:40