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

C++ 取消引用的双链接列表头为空,c++,doubly-linked-list,C++,Doubly Linked List,我的头指针应该是空的,因为我不想 当我制作我的链表时,它可能有任何价值 我知道你不能取消对空值的引用, 但我只想指出它的下一个节点是新的。 有人能解释一下我如何指向头部节点指针吗 void-dlist::向前推(int值){ node*p=新节点(); 节点*tempH=head(); tempH->next=p;//中断 /*********************************************************** 我的头指针被设置为空,因为我不想 当我制作我的链表时

我的头指针应该是空的,因为我不想 当我制作我的链表时,它可能有任何价值

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

void-dlist::向前推(int值){
node*p=新节点();
节点*tempH=head();
tempH->next=p;//中断
/***********************************************************
我的头指针被设置为空,因为我不想
当我制作我的链表时,它可能有任何价值。
我知道你不能取消对空值的引用,
但我只想指出它的下一个节点是新的。
有人能解释一下我如何指向头部节点指针吗?
************************************************************/
p->value=value;
p->next=tempH->next;
p->prev=tempH;
p->next->prev=p;
p->prev->next=p;
}
#pragma一次
#包括
类列表{
公众:
dlist(){}
//实现析构函数,删除所有节点
//~dlist();
结构节点{
int值;
节点*下一步;
节点*prev;
};
node*head()常量{return\u head;}
node*tail()常量{return\u tail;}
无效推力前(int值);
私人:
节点*_头=nullptr;
节点*_tail=nullptr;
};

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

dlist::dlist() {
  _head = nullptr;
}
此外,如果您最终删除了列表中的最后一项,您还需要将_head=nullptr

在取消引用之前,请确保检查head是否为null

 if(_head == nullptr){
     _head = new node(...);
 }
如果要添加到未初始化列表中,则insert函数将负责将第一个节点分配给头部


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

这里最实用的解决方案是仅将哨兵节点用于头部和尾部。或者,只有一个哨兵节点,代表两者。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);
    }
};
模板类数据列表{
结构节点头{
节点_头*next;
节点_头*prev;
};
结构节点:公共节点\u头{
T元素;
};
//将节点\头指针转换为节点指针
节点*节点\来自\头(节点\头*p){
返回静态_-cast(p);
}
};
使用这种方法,您的哨兵节点是一个
node\u头
,所有包含节点的实际元素都是
node
s。您的内部算法都在
node\u header
s上工作,直到您需要实际检索节点的元素,此时您可以使用
node\u from\u header()
检索包含节点的完整元素


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

在取消引用之前,为
\u head
分配一些内容?此外,你的问题令人困惑,因为它是这样写的:我知道我不能做X,但我如何做X?简而言之,你不能。头部节点不能为空。您必须为其分配内存,以便将其
下一个
指向新的内容。我想真正的问题是:你想实现什么?“我的头指针应该是空的[…]我只想把它的下一个节点指向新的东西。”如果它是空的,就没有“它”来设置它的下一个指针。在设置头部节点的下一个指针之前,需要分配头部节点。是否在
新建
之后
删除