解題思路:
如果不要求時間複雜度爲O(1),我們可以找出p的前驅結點,然後很容易就刪除p。
現在要求時間複雜度爲O(1),因爲p不是最後一個結點,知道結點p我們可以刪除p的後繼結點,那麼我們可以把p的後繼結點元素的值賦給p結點元素的值。
ADT定義如下
#define ElemType int
typedef struct LNode{
ElemType data;
LNode *next;
}LNode,*LinkList;
算法實現:
void deleteNode(LNode* &p)
{
if(p==NULL||p->next==NULL) return;//如果p爲空或爲單鏈表中最後一個結點不符合題意,直接返回
LNode* q=p->next;//q爲p的後繼結點
p->data=q->data;
p->next=q->next;//從單鏈表中刪除結點q
free(q);//釋放結點q
q=NULL;//將結點q置爲空,防止它成爲野指針
}
拓展:如果刪除的結點p可能是最後一個結點,怎麼辦。
解題思路:此時只能保證刪除結點的平均時間複雜度爲O(1),當p不是最後一個結點,時間複雜度爲O(1),當p是最後一個結點時,時間複雜度爲O(n)。
算法實現:
void deleteNode(LinkList &L,LNode* &p)
{
if(p==NULL||L==NULL) return;//如果p爲空或單鏈表L爲空不符合題意,直接返回
if(p->next) //如果p不是最後一個結點
{
LNode* q=p->next;//q爲p的後繼結點
p->data=q->data;
p->next=q->next;//從單鏈表中刪除結點q
free(q);//釋放結點q
q=NULL;//將結點q置爲空,防止它成爲野指針
}
else //如果p是最後一個結點
{
LNode* pre=L;//用pre表示p的前驅結點
while(pre->next) //保持pre有後繼結點
{
if(pre->next==p)//如果pre是p的前驅結點
{
pre->next=p->next;//將結點p從單鏈表中刪除
free(p);//釋放結點p
p=NULL;//將結點p置爲空,防止它成爲野指針
break;
}
}
}
}