双向链表添加元素

时间:2014-10-30 23:10:53

标签: c++ list reference

我是一个单一的任务,不幸的是,遇到了一个问题。 我仍然在努力使用指针和参考文献,所以我很难找到解决方案,即使我已经搜索了一整天。

以下是我的代码的基本部分:

struct BuenoList
{
    int value;
    BuenoList* prev;
    BuenoList* next;
};

声明:

void insertNode(BuenoList*, int);

定义:

void insertNode(BuenoList* tail, int _id)
{
    BuenoList* temp = new BuenoList;

    temp->value = _id;
    temp->prev = tail;
    tail->next = temp;
    tail = temp;
    tail->next = NULL;
}

现在,在main()中我这样做:

int main(int argc, char **argv)
{
    BuenoList* BuenoListing = new BuenoList;
    BuenoListing->value = 1;
    BuenoListing->prev = NULL;
    BuenoListing->next = NULL;

    BuenoList* BuenoHead = BuenoListing;
    BuenoList* BuenoTail = BuenoListing;

    insertNode(BuenoTail, 2); // Add value 2 to the list
    insertNode(BuenoTail, 3); // Add value 3 to the list

    return 0;
}

好的,这就是问题所在: 当我从第一个元素打印列表时,它打印如下:
1
1 2
1 3
显然这条线

  

insertNode(BuenoTail,3);

覆盖值2.
我的猜测是,BuenoTail不会改变,因此参考文献一定存在问题。

我该如何解决这个问题? 打印应为:1 2 3

@EDIT

void deleteNode(BuenoList*& tail, int _id) // Search list for specified value and delete it
{
    BuenoList* temp = tail;

    while (temp->prev != NULL)
    {
        if (temp->value == _id) break; 
        else temp = temp->prev;
    }

    if (temp->value == _id)
    {
        temp->prev = temp->next;
        free(temp);
    }
    else std::cout << "ERROR KEY DOES NOT EXIST\n";
}

3 个答案:

答案 0 :(得分:2)

您正在tail内更新insertNode(),但更新的值不会以任何方式传回给调用方。所以BuenoTail不会像你怀疑的那样改变。

解决这个问题的一个简单方法是将您的功能更改为:

BuenoList *insertNode(BuenoList* tail, int _id)

并从该函数返回新的tail。同时将呼叫更改为

BuenoTail = insertNode(BuenoTail, 2); // Add value 2 to the list

答案 1 :(得分:2)

考虑到您希望保持代码结构相同,我将向您展示两种可能的解决方案。在C方式中,您可以使用指向指针的指针来更新头部和尾部指针。或者,在C ++中,您可以通过引用传递头尾指针。就个人而言,在C ++中我会创建一个LinkedList类来跟踪你的头部和尾部节点。

按引用传递指针(C ++)

要通过引用传递指针,请先更改insertNode声明

void insertNode(BuenoList *&tail, int _id);

接下来,使用相同的函数参数更改insertNode定义。就是这样,你的代码现在应该可以工作了。此分钟更改有效,因为tail函数中的insertNode节点与tail函数中的main节点别名。

通过指针(C)传递指针

我知道您放了一个C ++标记,但您也可以使用更像C的方法更新headtail个节点。首先,在main函数中,您需要声明BuenoHeadBuenoTail作为指针的指针。

int main(int argc, char **argv)
{
    BuenoList* BuenoListing = new BuenoList;
    BuenoListing->value = 1;
    BuenoListing->prev = NULL;
    BuenoListing->next = NULL;

    BuenoList** BuenoHead = new BuenoList*;
    BuenoList** BuenoTail = new BuenoList*;
    *BuenoHead = BuenoListing;
    *BuenoTail = BuenoListing;

    insertNode(BuenoTail, 2); // Add value 2 to the list
    insertNode(BuenoTail, 3); // Add value 3 to the list

    return 0;
}

然后,您需要更新insertNode函数声明以获取指针指针。

void insertNode(BuenoList** tail, int _id);

然后,您需要更新函数定义以正确地指向指针,

void insertNode(BuenoList** tail, int _id) 
{
    BuenoList* temp = new BuenoList;

    temp->value = _id;
    temp->prev = *tail;
    temp->next = NULL;
    (*tail)->next = temp;
    *tail = temp;
}

修改

删除节点

您修改了问题,请求删除节点方面的帮助。您的deleteNode功能存在一些问题。

  1. 您将newfree混合。只要您使用new进行分配,就应该相应地使用delete
  2. 您无需检查temp->prev是否temp即可致电NULL
  3. 您需要更改函数参数以包含head指针。可能会发现您要删除的节点是链接列表的头部。如果是这样,您需要相应地更新头节点。
  4. 您需要检查要删除的节点是否在列表中间,列表的头部,列表的尾部,或者是否是列表的唯一节点。每种情况都需要不同的操作来更新链接列表。
  5. 考虑到这是一项大学任务,我不想给你全面的解决方案。这是一个部分修改的deleteNode函数。我留下了一些零件供你填写。希望这会有所帮助。也许下次再重点关注这个问题,所以我不必给出部分解决方案。

    void deleteNode(BuenoList*& tail, BuenoList*& head, int _id) {
        BuenoList* toDelete;
        toDelete = tail;
    
        // Traverse list and find node to delete
        while( ( toDelete != NULL ) && ( toDelete->value != _id ) ) {
            toDelete = toDelete->prev;
        }
    
        // If node not found, return
        if( toDelete == NULL ) {
            std::cout << "ERROR KEY DOES NOT EXIST\n";
            return;
        }
    
        // Check to see if node to delete is tail
        if( toDelete == tail ) {
            if( toDelete->prev != NULL ) {
                tail = toDelete->prev;
                tail->next = NULL;              
            } else { //Deleting only node in list
                tail = NULL;
                head = NULL;
            }
            delete toDelete;
            return;
        }
    
        // Check to see if node to delete is head
        if( toDelete == head ) {
            // FILL OUT WHAT TO DO HERE
            return;
        }
    
        // Node to delete is neither head nor tail.
        // FILL OUT WHAT TO DO HERE
        return;
    }
    

答案 2 :(得分:1)

您可能需要考虑使用节点结构和列表结构:

struct BuenoNode
{
    int value;
    BuenoNode* prev;
    BuenoNode* next;
};

struct BuenoList
{
    BuenoNode* head;
    BuenoNode* tail;
    size_t count; // having a count would be optional
}

list函数将获取指向列表结构的指针,例如InsertNode(BuenoList * blptr,int data);列表结构将被初始化,以便head和tail指针== NULL,并且您需要检查是否将节点添加到空列表或删除列表中的唯一节点以最终得到一个空列表。