0

我有这个删除功能:

Node* deleteNode(Node *head, Node *node)
{
    if (head != 0)
    {
        if (head == node)
            head = head->next;
        else
            head->next = deleteNode(head->next, node);
    }
    return head;
}

但是为了更清楚(因为我的程序的其余功能都在一个类中),我想把它变成这样:

void List::deleteNode()
{
    //the code comes here
}

(我想从单链表的开头删除,不想使用库。)

4

2 回答 2

3

就像是

void List::deleteNode()
{
    /* I suppose you have Node *head in your List class */
    if(head == NULL)
        return;

    Node * temp = head;
    head = head -> next;

    delete temp;
}

我认为“deleteHead”是这个函数的一个更好的名字。

于 2013-06-07T18:53:22.157 回答
0

我认为你的做法是错误的,你应该首先考虑课堂的外观和感觉,然后考虑里面发生了什么。当我考虑将代码放入一个类中时,特别是处理类似列表的代码时,我首先制作一个类需要支持的操作(追加、擦除、查找?、索引?)的心理列表。然后,我开始考虑我希望类具有的接口。然后,将代码放入类通常是一小步,因为大部分已经由前面的两个步骤决定了。

查看您的代码,我看到返回值仅用于next在递归调用后重置前一个元素的指针。因此,您可以将该功能一分为二,供列表的用户使用,另一种仅供内部使用。这一点很重要,因为这意味着类的接口只需要向外部(“公共”)显示类用户的接口。它在内部做的是自己的事情。这允许您将其从递归更改为迭代(这将更有效),而不会打扰类的用户。

现在,在您的情况下,您有一个要放入课程的列表。您可以从列表中删除元素,您可以在其中通过地址指定元素。这不会破坏元素,而是将其留给调用者(原始指针总是询问所有权问题,但这是一个不同的问题)。其他任何事情对我来说都是未知的,例如如何填充列表或如何分配节点。这给了我这个擦除操作的用例:

List l;
... // fill l
Node* n = ... // some node
l.erase(n);
delete n;

对于列表类型,这看起来像这样:

struct List
{
    void erase(Node* n)
    {
        m_head = doErase(m_head, n);
    }
private:
    static Node* doErase(Node* head, Node* node)
    {
        ... // your function here
    }

    Node* m_head;
};

请注意,仍然缺少一些东西,特别是您想让您的类不可复制,并且您必须决定当节点为空(例如assert(n);in erase())或不在列表中(throw invalid_argument("node not element of list");in do_erase())时要做什么。但是,我希望这可以帮助您入门。

于 2013-06-08T09:27:03.130 回答