简体   繁体   中英

insertion sort linked list c++

I'm trying to write a code to sort a linked list containing integers but its not working how I thought it would based on my reasoning I worked out for it with pencil and paper. Instead of traversing through the list, it compares the first pair of values, deletes the second value in the list and returns the remainder of the list. My method code is:

//typedef Node * ListType;

void insertionSort(ListType &list) {
    ListType p = list;
    Node * curr;
    if(p == NULL || p->next == NULL){
        return;
    }
    while(p != NULL){
        curr = p->next;
        if(curr == NULL){
            break;
        }
        if(p->data > curr->data){
            p->next = curr->next;
            curr->next = p;
        }
        p = p->next;
    }
}

Say, for instance I start with a list: 5 2 3 4 The output I get after calling this method on this list is: 5 3 4

I'm not comfortable with pointers. Any help is appreciated!

This kind of a task works much better if instead of a pointer, you use a pointer to a pointer. It also works better if the new element is passed separately, instead of being "pre-inserted" at the beginning of the list.

But, let's go with what you have, and the new node is pre-inserted at the beginning of the list, and you want to move it to the right position.

Then, it's going to be something like this:

#include <iostream>

class Node {

public:

    Node *next;

    int data;
};

typedef Node * ListType;

void insertionSort(ListType &list) {
    ListType *p = &list;

    while ( (*p)->next && (*p)->next->data < (*p)->data)
    {
        ListType node= *p;

        *p=node->next;

        node->next=node->next->next;

        (*p)->next=node;

        p= &(*p)->next;
    }
}

int main()
{
    Node *head=0;

    int n;

    while (std::cout << ">>> ", std::cin >> n)
    {
        Node *p=new Node;

        p->data=n;

        p->next=head;
        head=p;

        insertionSort(head);

        for (p=head; p; p=p->next)
            std::cout << p->data << " ";
        std::cout << std::endl;
    }
}

Sample results:

$ ./t
>>> 5
5 
>>> 7
5 7 
>>> 1
1 5 7 
>>> 3
1 3 5 7 
>>> 9
1 3 5 7 9 
>>> 6
1 3 5 6 7 9 
>>> 0
0 1 3 5 6 7 9 

The trick here that instead of p being a pointer to the node you're inserting, p is the pointer to the pointer to the node that's being inserted. So, if you need to "push" the new node further down the list, the "previous" pointer is *p , which you can easily update now.

Even though this looks confusing at first, this is far less messy that keeping track of the "previous" node, whose next pointer you need to update. All the if statement hairballs go away completely. That's where all the confusion comes from.

Also, if, as I mentioned initially, the new node is not preinserted at the beginning of the list, and gets passed as a separate pointer then this becomes much easier to understand. But, that was your starting point, so...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM