You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中双向链表头插需判空,单向链表为何无需?

为什么C++中双向链表的头插方法与单向链表不同?

先看两段分别实现单向链表和双向链表头插功能的C++代码,核心疑问是:单向链表的头插函数不需要处理head为NULL的特殊情况,但双向链表如果不做判空处理就无法正常运行,这是为什么?

单向链表实现代码

#include <iostream> 

using namespace std ;

// starting with linked list 

class node {

public : 
int data ; 
node * next ; 

// constructor 
node ( int value){
data = value ;  
next = NULL ; 
  }
};

int insertathead( node *&head , int data  ){

   node*newhead ;
   newhead = new node(data) ;  
newhead -> next = head ; 
head = newhead ; 

} 

void print(node*& head)
{
 node* temp = head;

while (temp != NULL) {
  cout << temp->data << " -> ";
  temp = temp->next;
}
cout << "NULL" << endl;
}

int main () {  

node* node1 = NULL  ; 
insertathead(node1, 5 )  ;  
insertathead( node1 , 10) ;  
insertathead(node1 , 15 ) ;
insertathead( node1 , 20 ) ;
insertathead( node1 , 30 ) ; 
print ( node1 ) ;

return 0 ; 
}

双向链表实现代码

#include <iostream> 
using namespace std  ; 
class node {
 public : 

int data; 
node*next ; 
node* prev ; 
// constructor 
node( int data )
{
   this -> data = data ; 
   next = NULL ; 
   prev = NULL ; 
}

} ; 

void insertathead ( node*&head , int d  ) {
   if ( head == NULL ) {
      node*temp = new node(d) ; 
       head = temp ; 
        }
      else 
     {node*temp = new node(d) ; 
         temp -> next = head ; 
       head  -> prev = temp ; 
         head  = temp ;} 
            }

void print ( node**head ){
node*temp = *head ; 
while ( temp != NULL )
 {
   cout << temp -> data << " ->  " ; 

 temp = temp -> next ; 
}
cout << "NULL " ; 
}
int main () { 
node* head = NULL ; 
insertathead( head , 5 ) ;
insertathead( head , 10) ;  
insertathead( head , 15 ) ;
insertathead(head , 20 ) ;
insertathead(head , 30 ) ; 

print ( &head ) ;

return 0 ; 

}

核心疑问

在单向链表的insertathead函数中无需处理head为NULL的特殊情况,但双向链表若不加入该判空逻辑则无法正常打印链表,请问这是为什么?

原因解析

直接拆解两种链表头插的操作差异:

  • 单向链表的头插逻辑
    当head为NULL时,执行newhead->next = head只是把新节点的next设为NULL,之后把head指向新节点。整个过程没有对head指向的内存进行读写——毕竟此时head是空指针,我们只操作新节点的成员,不会触发空指针访问错误,所以不需要判空。

  • 双向链表的头插逻辑(无判空时的问题)
    如果去掉双向链表insertathead里的if(head==NULL)判断,第一次插入节点(head为NULL)时,代码会执行:

temp -> next = head; // 这步没问题,temp->next被设为NULL
head -> prev = temp; // 这里直接报错!head是NULL,访问head->prev属于空指针解引用,会触发程序崩溃、打印乱码等未定义行为

双向链表需要维护prev指针,头插时需要修改原head的prev指向新节点。但当原head是NULL时,根本没有可访问的内存空间去赋值,这就导致了错误。而单向链表没有这一步修改原头节点成员的操作,所以不需要判空。

简单总结:单向链表头插只操作新节点的next,不碰原head的成员;双向链表头插需要修改原head的prev,当原head为空时这步操作会引发空指针错误,因此必须先判空处理第一个节点的情况。


内容的提问来源于stack exchange,提问作者sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:54:18