使用索引C ++删除节点的双链表

时间:2015-04-26 01:53:12

标签: c++ nodes doubly-linked-list

[在此输入链接说明] [1]因此,我一直在处理我正在处理的这个程序的问题。我是编程新手,但我非常坚定地学习这门语言。

我必须在程序中使用这3种不同的结构,所以指针真的开始让我失望了。该函数还必须返回新更新的songList。这就是我到目前为止所写的内容。问题是实际上没有删除任何东西,所以它只是被覆盖在函数中。如果有人可以请你展示如何做到这一点,将不胜感激。我已经取出了一些函数和switch语句来压缩这篇文章。主要目标是当选择删除功能时,它将要求用户选择它想要删除的歌曲的索引。然后当调用该函数时,它将该索引和songList作为参数。它将删除节点并返回列表。

1 个答案:

答案 0 :(得分:1)

  

我必须在程序中使用这3种不同的结构,所以指针真的开始让我失望了。

对于初学者来说,在C ++中,你真的应该使用std::list类,让它为你管理指针。

  

该函数还必须返回新更新的songList

您没有返回更新的列表,而是返回更新列表中的第一个节点。这本身就是多余的,因为您返回的是与您相同的字段,然后将返回的值返回给。返回值不是必需的,因为调用者知道正在修改哪个列表。

  

问题是实际上没有删除任何东西,所以它只是在函数中被覆盖。

您执行的removeSong()过于复杂,无法满足需要做的事情。它没有正确管理节点指针,也不是delete来自内存的任何东西。

此外,您的f案例实际上并未清除列表,只删除第一个节点而不考虑可能存在的后续节点,因此它们都在内存中泄露。正确的清晰算法需要循环删除每个节点的整个列表。

  

如果有人可以请您展示如何做到这一点,我们将不胜感激。

试试这个:

#include <iostream>
#include <string>

using namespace std;

struct Song
{
    int id;
    string name;
    string singerName;
};

struct SongNode
{
    Song sg;
    SongNode *previousNode;
    SongNode *nextNode;
};

struct SongDoublyLinkedList
{
    SongNode *firstElement;
    SongNode *lastElement;
};

void addSong(SongDoublyLinkedList *songList);
void displayListElements(SongDoublyLinkedList *songList);
void displayLastElement(SongDoublyLinkedList *songList);
void removeSong(SongDoublyLinkedList *songList, int index);
void clearList(SongDoublyLinkedList *songList);

int main()
{
    SongDoublyLinkedList songList;
    songList.firstElement = NULL; 
    songList.lastElement = NULL; 
    bool question = true;

    while (question == true)
    {
        char letter;
        cout << "\nEnter the letter of what you'd like to do next: " << endl;
        cout << " a = Add a New Song" << endl;
        cout << " b = Display List of Songs" << endl;
        cout << " c = Terminate Program" << endl;
        cout << " d = Display the Last Song in the List" << endl;
        cout << " e = Delete a Certain Song" << endl;
        cout << " f = Clear all Songs" << endl;
        cin >> letter;

        switch (letter)
        {
            case 'a':
            { 
                addSong(&songList);
                break;
            }

            case 'b': 
            {
                displayListElements(&songList);
                break;
            }

            case 'c':
            {
                question = false;
                break;
            }

            case 'd':
            {
                displayLastElement(&songList);
                break;
            }

            case 'e':
            {
                int indexNumber;
                cout << "Here is ";
                displayListElements(&songList);
                cout << "Enter the index of the song you'd like to delete ";
                cout << "(First Song = 0)" << endl;
                cout << "Enter Here: ";
                cin >> indexNumber;
                removeSong(&songList, indexNumber);
                break;
            }

            case 'f':
            {
                clearList(&songList);
                break;
            }
        }
    }
    return 0;
}

void addSong(SongDoublyLinkedList *songList)
{
    SongNode *songTemp = new SongNode;
    songTemp->previousNode = NULL; // Note: Important!
    songTemp->nextNode = NULL; // Note: Important!

    cout << "Enter The New Song's ID: ";
    cin >> songTemp->sg.id;
    cout << "Enter The New Song's Name: ";
    cin >> songTemp->sg.name;
    cout << "Enter The Singer's Name: ";
    cin >> songTemp->sg.singerName;

    if (songList->firstElement == NULL)
        songList->firstElement = songTemp;

    if (songList->lastElement != NULL)
    {
        songList->lastElement->nextNode = songTemp;
        songTemp->previousNode = songList->lastElement;
    }

    songList->lastElement = songTemp;
}

void displayListElements(SongDoublyLinkedList *songList)
{
    cout << "Your List: " << endl;

    SongNode *temp = songList->firstElement;
    while (temp != NULL)
    {
        cout << temp->sg.id << endl;
        cout << temp->sg.name << endl;
        cout << temp->sg.singerName << "\n" << endl;
        temp = temp->nextNode;
    }

    cout << endl;
}

void displayLastElement(SongDoublyLinkedList *songList)
{
    SongNode *lastSong = songList->lastElement;
    if (lastSong == NULL)
    {
        cout << "Your Song List is Empty. " << endl;
        return;
    }

    cout << "Your last song was : " << endl;
    cout << lastSong->sg.id << endl;
    cout << lastSong->sg.name << endl;
    cout << lastSong->sg.singerName << endl;
}

void removeSong(SongDoublyLinkedList *songList, int index)
{
    if (songList->firstElement == NULL)
    {
        cout << "Your Song List is Empty. " << endl;
        return;
    }

    SongNode *node = songList->firstElement;
    for(int i = 0; i < index; ++i)
    {
        node = node->nextNode;
        if (node == NULL)
        {
            cout << "Invalid index. " << endl;
            return;
        }
    }

    if (node->previousNode != NULL)
        node->previousNode->nextNode = node->nextNode;

    if (node->nextNode != NULL)
        node->nextNode->previousNode = node->previousNode;

    if (songList->firstElement == node)
        songList->firstElement = node->nextNode;

    if (songList->lastElement == node)
        songList->lastElement = node->previousNode;

    delete node;
}

void clearList(SongDoublyLinkedList *songList)
{
    SongNode *node = songList->firstElement;
    songList->firstElement = NULL;
    songList->lastElement = NULL;

    while (node != NULL)
    {
        SongNode *temp = node->nextNode;
        delete node;
        node = temp;
    }
}

或者,使用std::list

#include <iostream>
#include <string>
#include <list>
#include <algorithm>

using namespace std;

struct Song
{
    int id;
    string name;
    string singerName;
};

typedef std::list<Song> SongList;

void addSong(SongList *songList);
void displayListElements(SongList *songList);
void displayLastElement(SongList *songList);
void removeSong(SongList *songList, int index);
void clearList(SongList *songList);

int main()
{
    SongList songList;
    bool question = true;

    while (question == true)
    {
        char letter;
        cout << "\nEnter the letter of what you'd like to do next: " << endl;
        cout << " a = Add a New Song" << endl;
        cout << " b = Display List of Songs" << endl;
        cout << " c = Terminate Program" << endl;
        cout << " d = Display the Last Song in the List" << endl;
        cout << " e = Delete a Certain Song" << endl;
        cout << " f = Clear all Songs" << endl;
        cin >> letter;

        switch (letter)
        {
            case 'a':
            { 
                addSong(&songList);
                break;
            }

            case 'b': 
            {
                displayListElements(&songList);
                break;
            }

            case 'c':
            {
                question = false;
                break;
            }

            case 'd':
            {
                displayLastElement(&songList);
                break;
            }

            case 'e':
            {
                int indexNumber;
                cout << "Here is ";
                displayListElements(&songList);
                cout << "Enter the index of the song you'd like to delete ";
                cout << "(First Song = 0)" << endl;
                cout << "Enter Here: ";
                cin >> indexNumber;
                removeSong(&songList, indexNumber);
                break;
            }

            case 'f':
            {
                clearList(&songList);
                break;
            }
        }
    }
    return 0;
}

void addSong(SongList *songList)
{
    Song songTemp;

    cout << "Enter The New Song's ID: ";
    cin >> songTemp.id;
    cout << "Enter The New Song's Name: ";
    cin >> songTemp.name;
    cout << "Enter The Singer's Name: ";
    cin >> songTemp.singerName;

    songList->push_back(songTemp);
}

void displayListElements(SongList *songList)
{
    cout << "Your List: " << endl;

    SongList::iterator iter = songList->begin();
    while (iter != songList->end())
    {
        cout << iter->id << endl;
        cout << iter->name << endl;
        cout << iter->singerName << "\n" << endl;
        ++iter;
    }

    cout << endl;
}

void displayLastElement(SongList *songList)
{
    if (songList->empty())
    {
        cout << "Your Song List is Empty. " << endl;
        return;
    }

    SongList::reverse_iterator iter = songList->rbegin();
    cout << "Your last song was : " << endl;
    cout << iter->id << endl;
    cout << iter->name << endl;
    cout << iter->singerName << endl;
}

void removeSong(SongList *songList, int index)
{
    if (songList->empty())
    {
        cout << "Your Song List is Empty. " << endl;
        return;
    }

    SongList::iterator iter = std::advance(songList->begin(), index);
    if (iter == songList->end())
    {
        cout << "Invalid index. " << endl;
        return;
    }

    songList->erase(iter);
}

void clearList(SongList *songList)
{
    songList->clear();
}