当前位置: 首页 > 知识库问答 >
问题:

取消引用的双链接列表头为空

班泽语
2023-03-14

我的头指针应该是空的,因为我不希望在创建链接列表时它有任何值。

我知道不能取消对空值的引用,但我只想将它的下一个节点指向新的节点。有人能解释一下我如何指向头部节点指针吗?

void dlist::push_front(int value) {
    node *p = new node();
    node *tempH = head();
    tempH->next = p; //break
    /***********************************************************
    my head pointer is suposed to be null, because I don't want
    it to have any value when I make my linked list.

    I know that you can't dereference something that is null,
    but I just want to point it's next node to something new.
    can someone explane how I could point the head node pointer?
    ************************************************************/
    p->value = value;
    p->next = tempH->next;
    p->prev = tempH;
    p->next->prev = p;
    p->prev->next = p;
}
#pragma once
#include <ostream>

class dlist {
public:
    dlist() {}

    // Implement the destructor, to delete all the nodes
    //~dlist();

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

    node* head() const { return _head; }
    node* tail() const { return _tail; }
    void push_front(int value);
private:
    node* _head = nullptr;
    node* _tail = nullptr;
};

共有2个答案

丌官坚秉
2023-03-14

这里最实用的解决方案就是在头部和尾部使用哨兵节点。或者,只有一个哨兵节点,代表两者。sentinel节点的元素可以保持未初始化状态,您只需要为它们包含的下一个和上一个指针使用这些节点。要测试是否已到达列表的末尾,您需要测试指针是否指向sentinel节点,而不是测试空指针。

如果您希望列表元素较小,或者列表非常大,则可以使用普通节点作为哨兵。你会在空间上浪费一点内存来放置那些不会被使用的元素,但这可能没什么大不了的。如果你真的关心内存效率(比如,你正在写一个库),你可以有这样的东西:

template<typename T> class dlist {

    struct node_header {
        node_header* next;
        node_header* prev;
    };

    struct node : public node_header {
        T element;
    };

    // Convert a node_header pointer to a node pointer
    node* node_from_header(node_header* p) {
        return static_cast<node*>(p);
    }
};

使用这种方法,您的哨兵节点是一个node_header,所有实际的包含元素的节点都是节点s。您的内部算法都在node_headers上工作,直到您需要实际检索节点的元素,此时您可以使用node_from_header()来检索完整的包含元素的节点。

如果您绝对不想使用sentinel节点,则必须重写代码以直接使用头指针,而不是通过函数检索它,并添加用于处理空头指针的特殊情况代码。这不是一个好的选择。

佟阳焱
2023-03-14

在列表构造函数中,只需将head指针设置为null。

dlist::dlist() {
  _head = nullptr;
}

此外,如果你最终删除了列表中的最后一项,你还需要将_head=nullptr;

在取消引用之前,请务必检查head是否为null。

 if(_head == nullptr){
     _head = new node(...);
 }

如果要添加到未初始化的列表中,插入函数将负责将第一个节点分配给头部。

如果需要对列表进行排序,则需要考虑在新节点应先于头部节点的情况下头部的变化。

 类似资料:
  • 我已经得到了实现双向链表的框架。我被PushFront()方法难住了。方法应该将提供的元素添加到链表的前面,并且应该将地址返回到新的头节点。我对如何访问列表的当前头部感到困惑,以便我可以将其分配给pNext指针。到目前为止,PushTop()方法看起来是这样的: 元素类构造函数: 数据类: 主要: 我的理解是,您通常会在调用PushFron()时提供头的地址,但是因为我没有提供,我不确定如何访问它

  • 我一直试图理解为什么LRU缓存使用双重链接列表而不是单一链接列表? 如果按时间复杂度计算,它们的插入、更新和删除都是相同的。这是备忘单 是因为DLL中的双向指针用于更容易地将节点移动到后部还是前部??

  • 我正在尝试创建二维双链接圆形阵列,从txt文件读取数据并自动创建节点。我的程序正在正确地读取第一行,但当它到达下一行并开始创建下一个节点时,会出现空指针。我不明白为什么会这样,请帮帮我。 这些都是错误。Null指针在尝试创建第二个节点时发生。它正确地创建第一个节点,而不是紧接着创建空指针。 第77行=位置next=n; 第69行=插入后(head.prev, x); 第18行=mList。镶片(k

  • 我在分析一个删除节点的双链表函数。然而,我有点困惑。 为什么有一个tmp=p.prev和p.prev=tmp。这些额外线路的用途是什么?最后,为什么没有使用“del”删除节点?代码末尾不应该是“delp”吗? 非常感谢。

  • 我正在尝试为一个项目创建一个双链接列表容器。我不能使用任何std容器。必须对双链接列表进行排序。以下是我目前的代码: 我遇到的问题是在我的插入函数中。我正在使用调试器,并在以下行插入代码:list.insert(10);。 它正确地进入第一种情况,即head==nullptr并创建节点。当我进入下一行代码(list.insert(20))时,它会用这一行创建一个节点:node*node=newno

  • 问题内容: 我试图像这样使用PrintWriter: 但是Java抱怨: 无效不能取消引用 如果我做: 可行,有什么原因吗? 问题答案: 是。(和其他方法)的签名返回(不是)。您不能将调用链接到方法。