【问题标题】:Implimenting Doubly Linked List实现双向链表
【发布时间】:2021-11-18 01:40:57
【问题描述】:

我已经获得了实现双向链表的框架。我对 PushFront() 方法感到困惑。该方法应将提供的元素添加到链表的前面,并将地址返回给新的头节点。我对如何访问列表的当前头部感到困惑,所以我可以将它分配给 pNext 指针。 PushFront() 方法目前看起来是这样的:

Element* Element::PushFront(Element* d){
   Element* newElement = new Element(Data());    // Allocate space for new element
   newElement->ElementData = d->ElementData;    // Assign ElementData to the new  element                
   newElement->pNext = // Head address
   newElement->pPrev = NULL;
return nullptr;
}

元素类构造函数:

Element::Element(Data d){
   ElementData = d;
   pNext = NULL;
   pPrev = NULL;
}

数据类:

Data::Data(){
Name = "Unknown";
SN = 0;
Program = "Unknown";
}

Data::Data(string NameStr, unsigned int sNumber, string Prog) :
Name(NameStr), SN(sNumber), Program(Prog) {};

主要:

Element* pList = new Element(Data("Cam", 12345, "Testing1"));   
Element newE(Data("Bob", 335567, "Testing2"));
pList = pList->PushFront(&newE);

我的理解是,您通常会在调用 PushFront() 时提供头部的地址,但是由于没有提供我不确定如何访问它。

【问题讨论】:

  • Rubber Duckie 想知道您打算使用Element* d 做什么。只是为了从中获取数据?它必须有更好的用途,否则您只需传递数据。
  • pList 是列表的头部。在PushFront 方法中,pList 被称为this
  • @user3386109 谢谢。这是我的不理解。
  • 我认为您将链接列表与列表中的链接混为一谈。 Element 看起来应该是一个链接。它不应该知道什么是头,因为链接应该知道的唯一事情是它附加到的其他链接以及它包含的数据。一个链接可能是一个头,但它不应该知道这一点。头部是只有链表应该知道的细节。与PushFront 类似。链接不应该有前面。它只有一个prevnext,所以可能是一个insert_before 和一个insert_after。有前面的链表。
  • 有时我内心的小丑会努力出来......所以我很抱歉这句话:类的名称是“leaky c++ 101”吗? :) 如果将Element*p 传递到PushFront(),那么你也可以在main 中写:... Element (Data("Cam", 12345, "Testing1")); 然后传递自动变量的地址。这反过来又会导致破坏、移除等几乎不可能实现:)

标签: c++ linked-list doubly-linked-list function-definition


【解决方案1】:

使用您对列表定义的方法,该函数可以如下所示

Element * Element::PushFront( Element *d )
{
    Element *newElement = new Element( d->ElementData );

    newElement->pNext = this;
    newElement->pPrev = this->pPrev;
    this->pPrev = newElement;

    return newElement;
}

虽然这样的函数声明没有多大意义。该函数至少应该声明为

Element * Element::PushFront( const Data &d );

而不是

Element * Element::PushFront( Element *d );

甚至喜欢

Element * Element::PushFront( const char *Name, unsigned int SN, const char *Program );

请注意,最好再声明一个数据结构,该结构确实将表示双向链表,并且将包含指向元素类型的第一个(头)和最后一个(尾)对象的指针。列表。

【讨论】:

    【解决方案2】:

    我对如何访问列表的当前头部感到困惑

    当您在pList 实例上调用PushFront 方法时,this 引用将是pList,它被假定为列表的头部。主程序负责维护对头部的引用。

    请注意,有时会创建另一个类来表示列表,然后该类具有head 成员。但是,在这种情况下,您似乎没有这样的类,并且主程序必须自己管理头部,即pList

    PushFront 方法必须“帮助”主程序执行此操作,并返回对 new 头的引用。所以不要返回nullptr

    我真的不明白为什么在PushFront 中创建一个新的Element,因为你已经获得了一个作为参数传递的元素。我认为目的是将 那个 元素添加到列表中,而不是它的副本。

    所以:

    Element* Element::PushFront(Element* d){
       d->pNext = this;
       d->pPrev = NULL;
       return d;
    }
    

    在主程序中,我建议使用new 创建两个Element 实例,以便它们的内存管理是相同的:

    Element* pList = new Element(Data("Cam", 12345, "Testing1"));   
    Element* newE = new Element(Data("Bob", 335567, "Testing2"));
    pList = pList->PushFront(newE);
    

    【讨论】:

      最近更新 更多