题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。

分析:删除结点可以从链表的头结点开始顺序遍历,发现某个结点的next指向要删除的结点时,将该结点的next指向要删除的下一个结点。但是基于这种思路,得到的时间复杂度是O(n)。

删除结点只是让这个结点不出现在该链表中,可以采取覆盖的方式。也就是将下一个结点的内容复制到需要删除的结点上覆盖掉原有的内容。这样的话,就可以达到要求了。

NOTE:若要删除的结点为尾节点,我们仍要从头遍历该链表。

    若只有一个结点时,则不仅要删除该结点,还要将其置为NULL。

参考代码:

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int datatype;typedef struct LinkList
{datatype data;struct LinkList *next;}LinkList,*pLinkList,*pList;void InitLinkList(pList* pHead)
{assert(pHead);*pHead=NULL;
}void PrintList(pList list)
{pLinkList cur=list;printf("list is:");while(cur){printf("%d ",cur->data);cur=cur->next;}printf("over\n");
}pLinkList BuyNode(datatype x)
{pLinkList newNode=(pLinkList)malloc(sizeof(LinkList));newNode->data=x;newNode->next=NULL;return newNode;
}void PushBack(pList* pHead, datatype x)
{pLinkList  cur=*pHead;pLinkList newNode=BuyNode(x);if(cur==NULL){*pHead=newNode;return;}else{while(cur->next){cur=cur->next;}cur->next=newNode;}
}pLinkList Find(pList phead, datatype x)
{pLinkList cur=phead;if(cur==NULL){return NULL;}else{while(cur){if(cur->data==x){return cur;}else{cur=cur->next;}}}
}void DeleteNode(LinkList **pHead,LinkList *pDelete)
{if(!pHead || !pDelete)	{return;}//非尾节点if(pDelete->next!=NULL){LinkList *pNext=pDelete->next;pDelete->data=pNext->data;pDelete->next=pNext->next;free(pNext);pNext=NULL;}//一个节点else if(*pHead==pDelete){free(pDelete);pDelete=NULL;*pHead=NULL;}//尾节点else{LinkList *pNode=*pHead;while(pNode->next!=NULL){pNode=pNode->next;}pNode->next=NULL;free(pNode);pDelete=NULL;}
}void Test()
{pList mylist;InitLinkList(&mylist);PushBack(&mylist,1);PushBack(&mylist,2);PushBack(&mylist,3);PushBack(&mylist,4);PrintList(mylist);DeleteNode(&mylist, Find(mylist,2));PrintList(mylist);
}int main()
{Test();system("pause");return 0;
}