您的位置:首页 > 职场人生

【剑指offer】面试题13、在 O(1)时间上删除链表结点

2015-06-18 18:33 363 查看
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:
typedef struct Node
{
int m_nValue;
struct Node *m_pNext;
}ListNode, *pListNode;

void DeleteNode(ListNode **pHead, ListNode *pToBeDeleted);


 在单链表中删除一个结点,最常用的做法莫过于从链表的头结点开始,顺序遍历查找并找到要删除的结点,然后再进行删除操作。

 比如在下图(a)所示的链表中,我们想要删除结点 i,我们就可以从头结点开始遍历该链表,遍历到 h 结点时,会发现 h 的下一个结点 i 就是我们所要删除的结点。这样我们可以把 h 的 m_pNext指向 i 的下个结点 j。指针调整之后我们就可以安全删除结点 i 并保证链表没有断开。

这种顺序查找的时间复杂度为 O(n)。

// deleteNode.c
#include "stdio.h"
#include "stdlib.h"

#define N 10

typedef struct Node
{
int m_nValue;
struct Node *m_pNext;
}ListNode, *pListNode;

void deleteNode(ListNode **pHead, ListNode *pToBeDeleted);
// 获得要删除结点
ListNode *getNodeIndex(ListNode *pHead, int index);

void createList(ListNode **pHead, int len)
{
ListNode *pTail = NULL;

while(len--)
{
ListNode *pNew = (ListNode*)malloc(sizeof(ListNode));
pNew->m_nValue = rand()%100;
pNew->m_pNext = NULL;

if(*pHead == NULL)
{
*pHead = pNew;
pTail = pNew;
}
else
{
pTail->m_pNext = pNew;
pTail = pNew;
}
}
}

void printList(ListNode *pHead)
{
while(pHead != NULL)
{
printf("%3d ", pHead->m_nValue);
pHead = pHead->m_pNext;
}
printf("\n");
}

void deleteNode(ListNode **pHead, ListNode *pToBeDeleted)
{
if(!pHead || !pToBeDeleted)
return;

// 链表有多个结点,并且删除的不是尾结点
if(pToBeDeleted->m_pNext != NULL)
{
ListNode *pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;

free(pNext);
pNext = NULL;
}
// 还剩两种情况:要么链表只有一个结点,要么删除的是尾结点(含有多个结点)
else if(*pHead == pToBeDeleted)// 链表只有一个结点
{
free(pToBeDeleted);
pToBeDeleted = NULL;
*pHead = NULL;
}
else // 多个结点,并且删除的是尾结点
{
ListNode *curNode = *pHead;
while(curNode->m_pNext != pToBeDeleted) // 找到删除结点的前一个结点
curNode = curNode->m_pNext;

curNode->m_pNext = NULL;
free(pToBeDeleted);
pToBeDeleted = NULL;
}
}

ListNode *getNodeIndex(ListNode *pHead, int index)
{
if(!pHead || index < 0)
return NULL;

ListNode *node = pHead;
while(--index)
node = node->m_pNext;
return node;
}

int main(int argc, char const *argv[])
{
ListNode *pHead = NULL;

createList(&pHead, N);
printf("Before: ");
printList(pHead);

ListNode *pToBeDeleted = getNodeIndex(pHead, 3);
deleteNode(&pHead, pToBeDeleted);
printf("After: ");
printList(pHead);

return 0;
}


View Code

本文完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: