删除单链表某个结点

题目:删除带头结点的单链表L中的结点p,p不是最后一个结点,要求时间复杂度为O(1)。

解题思路:
如果不要求时间复杂度为O(1),我们可以找出p的前驱结点,然后很容易就删除p。
现在要求时间复杂度为O(1),因为p不是最后一个结点,知道结点p我们可以删除p的后继结点,那么我们可以把p的后继结点元素的值赋给p结点元素的值。

ADT定义如下
#define ElemType int
typedef struct LNode{
    ElemType data;
    LNode *next;

}LNode,*LinkList;


算法实现:

[cpp]  view plain copy
  1. void deleteNode(LNode* &p)  
  2. {  
  3.     if(p==NULL||p->next==NULL) return;//如果p为空或为单链表中最后一个结点不符合题意,直接返回  
  4.     LNode* q=p->next;//q为p的后继结点  
  5.     p->data=q->data;  
  6.     p->next=q->next;//从单链表中删除结点q  
  7.   
  8.     free(q);//释放结点q  
  9.     q=NULL;//将结点q置为空,防止它成为野指针  
  10. }  

拓展:如果删除的结点p可能是最后一个结点,怎么办。

解题思路:此时只能保证删除结点的平均时间复杂度为O(1),当p不是最后一个结点,时间复杂度为O(1),当p是最后一个结点时,时间复杂度为O(n)。

算法实现:

[cpp]  view plain copy
  1. void deleteNode(LinkList &L,LNode* &p)  
  2. {  
  3.     if(p==NULL||L==NULL) return;//如果p为空或单链表L为空不符合题意,直接返回  
  4.     if(p->next) //如果p不是最后一个结点  
  5.     {  
  6.         LNode* q=p->next;//q为p的后继结点  
  7.         p->data=q->data;  
  8.         p->next=q->next;//从单链表中删除结点q  
  9.   
  10.         free(q);//释放结点q  
  11.         q=NULL;//将结点q置为空,防止它成为野指针  
  12.       
  13.     }  
  14.     else //如果p是最后一个结点  
  15.     {  
  16.         LNode* pre=L;//用pre表示p的前驱结点  
  17.         while(pre->next) //保持pre有后继结点  
  18.         {  
  19.             if(pre->next==p)//如果pre是p的前驱结点  
  20.             {  
  21.                 pre->next=p->next;//将结点p从单链表中删除  
  22.                 free(p);//释放结点p  
  23.                             p=NULL;//将结点p置为空,防止它成为野指针  
  24.                                 break;  
  25.             }  
  26.         }  
  27.     }  
  28.       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值