Bubble-sorting doubly linked list

2019-07-22 18:35发布

问题:

I have a problem with my bubble-sorting function for the doubly linked list. It is working when I'm sorting the nodes in the singly linked way (only with ->next), but I can't make it work with ->prev pointers. Here is the code I'm using:

void sort(int count)
{
    struct data *tmp,*current,*nextone;
    int i,j;
    for(i=0;i<count;i++)
    {
        current = first;
        for(j=0;j<count-1-i;j++ )
        {
            if(current->number > current->next->number)
            {
                nextone = current->next;
                current->next = nextone->next;
                nextone->next = current;
                if(current == first)
                {
                    first = nextone;
                    current = nextone;
                }
                else
                {
                    current = nextone;
                    tmp->next = nextone;
                }
            }
            tmp = current;
            current = current->next;
        }
    }
}

And this is the structure I'm using (with the global variables for the first and last element of the list):

struct data    
{
    int id;
    char name[20];
    int number;
    struct data *next;
    struct data *prev;
};

struct data *first = NULL;
struct data *last = NULL;

回答1:

Below logic would work.

I would follow similar algorithm... If you want to move the entire nodes...

struct data *before, *after;
if(current->number > current->next->number)
{
    before = current->prev;
    after = current->next;
    if(before != NULL){
        before->next = after;
    }
    current->next = after->next;
    current->prev = after;
    after->next = current;
    after->previous = before;
}

Alternatively, you can simply swap the numbers in the nodes without bothering to move entire nodes, if sorting of the data is the purpose. You can expand the below logic to include swapping of both char array and id as well.

if(current->number > current->next->number)
{
    int tempNum = current->number;
    current->number = current->next->number;
    current->next->number = tempNum;
}


回答2:

You just need to sit down and think about it for a bit.

Assigning first? Well the previous must be null.

Assigning last? Next must be null.

Anything else you need to do a little swap-dance with previous & next of the elements you are swapping.

A much easier way (that will quickly become faster too for larger array sizes) is to allocate an array of pointers, fill those with pointers to the elements, qsort the array then do another pass to re-wire the pointers (and delete the temp array).



回答3:

One easier way is just to copy the data of the node, you can swap the data but the pointer to the node.

if(current->number > current->next->number){
   swap(current->id,current->next->id);
   swap(current->name,current->next->name);
    swap(current->number,current->next->number);
}

With your method, you never set the previous pointer at all. You can sort the double linked list as single list at first, and then traversal the list again to set all the prev pointer.

Of course, you can sort the double linked list at a time, but it's a little complex to implement. You should consider 4 nodes each step, i.e current, current->next, as well as current->prev and current->next->next. When you want to swap current and current->next, you should set current->prev->next=current->next, current->next=current->next->next so on and so forth.