简体   繁体   中英

C++: Adding node to doubly linked list in alphabetical order

I'm trying to add nodes to a doubly linked list in alphabetical order with respect to the title element of the node. So far, I've tried iterating through the list and checking for the case (strcmp(title, currTitle) > 0) . However, iteration does not work (for reasons I'm not certain of), as the attempt listed below does not add any items to the linked list.

The set of four conditions for the if - else block successfully adds items to the list when not implemented with the attempt at sorting.

void SongList::addSongSorted(const Song &aSong)
{
    //sort inputs to the list by alphabetical order of the entire title
    char title[MAX_CHAR];
    char currTitle[MAX_CHAR];
    aSong.getTitle(title);

    Node * newNode = new Node(aSong);

    Node * curr = head;
    //Increment through list as added...this does not work
    for(curr = head; curr; curr = curr->next)
    {

        if(strcmp(title, currTitle) > 0)
        {

            if(!head)
            {
                head = newNode;
                tail = newNode;
                head->next = NULL;
                head->prev = NULL;
            }
            else if(head->prev == NULL)
            {
                newNode->next = head;
                head = newNode;
                newNode->prev = NULL;
            }

            else if(head->next == NULL)
            {
                curr->next = newNode;
                newNode->prev = curr;
                newNode->next = NULL;
                tail = newNode;
            }

            else
            {
                newNode->next = curr->next;
                newNode->prev = curr;
            }
        }
    }
}

How is it that incrementing through the list and adding at a node based on comparison of elements does not work? What is a solution?

As @verbose says, you never really assign a value to currTitle , try using curr.getTitle(currTitle) at the start of the loop, or using curr->title in its place.

With regards to inserting in order, you needn't worry about head 's previous value, only if the head itself is null, or the title comes before the head. You should iterate through the list, if the title comes after the current node, and the next node is null, you set curr to the next element (done in the for loop) and check again. If The next element is NULL, and the title comes after the current one, you have reached the end of the list, may insert the song, and break. If the song title comes before the current one, or is equal, you insert the new song before the current one and return. Example code below:

if(!head)
{
    // set head to currnode, as you have
    head = newNode;
    tail = head;
    next = NULL;
    prev = NULL;
    return; // no need to iterate through the list
}
bool inserted = false;
while (!inserted) 
{
    curr->song.getTitle(currTitle);
    if(strcmp(title, currTitle) > 0)
    {
        // If the title goes after the current title 
        if(curr->next == NULL)
        {
            // End of the list, insert after this node
            curr->next = newNode;
            newNode->prev = curr;
            newNode->next = NULL;
            tail = newNode;
            inserted = true;
        }
        // If we don't insert here, we iterate again
        curr = curr->next;
    }
    else 
    {
        // If the title is the same, or comes before the current title, insert before curr
        newNode->prev = curr->prev;
        newNode->next = curr;
        curr->prev = newNode;
        if (curr == head)
        {
            head = newNode;
        }
        inserted = true
    }
}

You are comparing the two strings but the second doesn't appear to ever be initialized. Presumably aSong.getTitle(title) copies the title of the current song to the title[] array. But when is anything ever copied to currTitle[] ?

So the elements of currTitle[] are garbage, and the comparison won't work. To fix this, compare the title of the song you want to insert to the titles of the songs already in the list. You probably want something like strcmp(title, curr->title) .

Of course you first need to check that a song actually exists before doing the comparison. Start by checking whether a song exists at head , and if not, insert the song as the head song. If there is already a song at the head, compare the two titles and determine whether the new song should be the new head, or whether it should go somewhere after the head. The rest of the logic should be straightforward.

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