链表面试题总结(二)

带头结点的单链表和不带头结点的单链表的区别

(1)从功能上讲,带头节点和不带头节点的单链表实现的功能是一样的,在删除和插入的效率是一样的,都是O(1)。
(2)从操作方面讲,带头节点的比不带头节点的单链表实现简单,一方面是不用改变头指针的指向,另一方面不管是在删除或者插入时,都保持了一致性,可以快速的定位链表中的第一个结点。
(3)如果为了在第一个数据元素前面加入新元素或者删除第一个节点时头指针的值不变,在第一个数据前面要加头节点。

带头节点的双向循环链表的尾插尾删

 void pushBack(ListNode* pHead,const int & data)
 {
      ListNode* newNode=new ListNode;
      newNode->data=data;

      newNode->pPre=pHead->pPre;
      pHead->pPre->pNext=newNode;
      newNode->pNext=pHead;
      pHead->pPre=newNode;
 }
void popBack(ListNode* pHead)
 {
     if(pHead->pPre==pHead)
          return;
      ListNode* Del=pHead->pPre;
      pHead->pPre=Del->pPre;
      Del->pPre->pNext=pHead;
      delete Del;
      Del=NULL;
  }

带头节点的双向循环链表的尾插尾删

void pushHead(ListNode* pHead,const int& data)
 {
     ListNode* newNode=new ListNode;
    newNode->data=data;

     newNode->pNext=pHead->pNext;
     pHead->pNext->pPre=newNode;
     pHead->pNext=newNode;                                                   
     newNode->pPre=pHead;

 }
 void popHead(ListNode* pHead)
 {
      if(pHead->pPre==pHead)
         return;
      ListNode* Del=pHead->pNext;
     if(Del->pNext==pHead)
     {
          pHead->pPre=pHead;
     }
     pHead->pNext=Del->pNext;
     Del->pNext->pPre=pHead;
     delete Del;
     Del=NULL;

   }

带头节点的双向循环链表的任意位置的插入【重要】

ListNode* Insert(ListNode* pos,const int& data)
  {
     assert(pos);
      ListNode* newNode=new ListNode;
     newNode->data=data;

     newNode->pPre=pos->pPre;
     pos->pPre->pNext=newNode;
     pos->pPre=newNode;
     newNode->pNext=pos;
     return newNode;
 }

带头节点的双向循环链表的任意位置的删除 【重要】

 ListNode* erase(ListNode* pos)
 {
     assert(pos);
      ListNode* pret=pos->pNext;
      pos->pNext->pPre=pos->pPre;
      pos->pPre->pNext=pos->pNext;
      delete pos;
      pos=NULL;
      return pret;
  }                                                                           
点赞