william_
william_

Reputation: 1133

bubble sort on link list is removing elements during swap

current uni student and i am trying to sort a link list by only swapping the links and not the data ( as per requirements)

my link definition is:

typedef struct iorb {
        int base_pri;
        struct iorb *link;
        char filler[100];
} IORB;

I am building the list like so:

void buildList(IORB **h, int size,int(*prio)(int)){
    int counter = size;
        // loop will run until the size of the list is reached 
        while(size > 0){ 
                IORB *temp = (IORB*)malloc(sizeof(IORB)); //alocating memory on the stack for the link list
                temp->base_pri = (rand() % 100); // assigning random number as the base pointer
                sprintf(temp->filler, "request %d : base priority = %d : priority = %d \n",
                counter, temp->base_pri,(*prio)(temp->base_pri));
                temp->link = *h; // making sure the head points to the next item in the list.
                *h = temp;
                counter--;
                size--;
                
        }
}

and this is my sort function:

void sortList(IORB* head,int (*prio)(int)){
    int swapped = 1;

    while(swapped)
    {
        //pointers for the last current and next node
        IORB **prev = &head, *curr, *next;

        swapped = 0;
        for(curr = head; curr; prev = &curr->link, curr = curr->link)
        {
            next = curr->link;

            if(next && (*prio)(curr->base_pri) > (*prio)(next->base_pri))
            {
                curr->link = next->link;
                next->link = curr;
                *prev = next;

                swapped = 1;
            }
        }
    }
}

priComp is an additional function defined as:

int priComp(int bs){
    return (bs * 3);
}

and to display the list:

void displayList(IORB* head){
    while(head != NULL)
    {
        printf("%s",head->filler);
        head = head->link;
        
    }
    
}

the problem I am having: after building the list and using the display function I can correctly see the list but after I call the sort function and reprint the list sometimes the list will print sorted but majority of the time I will be missing elements

for example -

before sort:

request 1 : base priority = 10 : priority = 30
request 2 : base priority = 3 : priority = 9
request 3 : base priority = 53 : priority = 159

after sort:

request 2 : base priority = 3 : priority = 9
request 1 : base priority = 10 : priority = 30

the list fails to print request 3. (it is not always the last element it skips but sometimes will skip an element in the middle of the list)

When i run the sort function through the debugger I can not pinpoint when the links are either being lost or removed. the loops and if statements seem to be flowing correctly.

Upvotes: 0

Views: 175

Answers (1)

Stef1611
Stef1611

Reputation: 2387

As suggested above in comments by trincot and WhozCraig, your list is sorted but the problem comes from the fact you have not the new head. I answer to your question with an ugly workaround because it seems that you could not change the function prototype. But, I insist it is not a good solution.

The null pointer of last list element is used to get back the head of the list.

First, add theses lines to the end of sortlist function.

IORB *curr;
for(curr = head; curr->link; curr = curr->link);
curr->link=head;

!!!!!!!!! DO NOT USE SORTLIST DIRECTLY. NOW, YOU HAVE AN INFINITE LOOP LIST !!!!

But call this function : uglyWorkaround(&mylist,priComp);

uglyWorkaround(IORB** mylist,int (*prio)(int))
{
    sortList(*mylist,priComp);

    IORB *curr = *mylist;    
    while(!((*prio)(curr->base_pri) > (*prio)(curr->link->base_pri)))
        curr = curr->link;
    *mylist=curr->link;
    curr->link=NULL;
}

*** Edit : To answer to comment about clarification on function prototype ***

The WhozCraig solution

void sortList2(IORB** head,int (*prio)(int)){
    int swapped = 1;

    while(swapped)
    {
        //pointers for the last current and next node
        IORB  **prev=head, *curr, *next;

        swapped = 0;
        for(curr = *head; curr; prev = &curr->link, curr = curr->link)
        {
            next = curr->link;

            if(next && (*prio)(curr->base_pri) > (*prio)(next->base_pri))
            {
                curr->link = next->link;
                next->link = curr;
                *prev = next;

                swapped = 1;
            }
        }
    }
}

And to call it : sortList2(&mylist,priComp);

Upvotes: 1

Related Questions