刪除單鏈表某個結點

題目:刪除帶頭結點的單鏈表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;


算法實現:

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;
			}
		}
	}
	
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章