剑指offer(4)-O(1)时间删除链表结点

来源:互联网 发布:软件开发可行性报告 编辑:程序博客网 时间:2024/05/21 14:48

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

struct ListNode{    int m_nValue;    ListNode* m_pNext;};void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted);

按照常规做法,从头结点一个一个顺序查找肯定是超时的,需要O(n)时间,可以考虑先将要删除结点的后继结点赋值给当前结点,然后将后继结点删掉,最后把当前结点与它的下下个结点相连不久行了么?
这个问题考察了对链表的基本操作,值得好好总结,完整代码如下:

// DeleteNode.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<iostream>using namespace std;struct ListNode{    int m_nValue;    ListNode* m_pNext;};ListNode* CreateListNode(int value){    ListNode* pNode = new ListNode();    pNode->m_nValue = value;    pNode->m_pNext = NULL;    return pNode;}void ConnectListNodes(ListNode* pCurrent, ListNode* pNext){    if (pCurrent == NULL)    {        cout << ("Error to connect two nodes.\n");        exit(1);    }    pCurrent->m_pNext = pNext;}void PrintListNode(ListNode* pNode){    if (pNode == NULL)    {        cout << ("The node is NULL\n");    }    else    {        cout << ("The key in node is :\n", pNode->m_nValue);    }}void PrintList(ListNode* pHead){    cout << ("PrintList starts.\n");    ListNode* pNode = pHead;    while (pNode != NULL)    {        cout << (pNode->m_nValue);        pNode = pNode->m_pNext;    }    cout << ("\nPrintList ends.\n");}void DestroyList(ListNode* pHead){    ListNode* pNode = pHead;    while (pNode != NULL)    {        pHead = pHead->m_pNext;        delete pNode;        pNode = pHead;    }}void AddToTail(ListNode** pHead, int value){    ListNode* pNew = new ListNode();    pNew->m_nValue = value;    pNew->m_pNext = NULL;    if (*pHead == NULL)    {        *pHead = pNew;    }    else    {        ListNode* pNode = *pHead;        while (pNode->m_pNext != NULL)            pNode = pNode->m_pNext;        pNode->m_pNext = pNew;    }}void RemoveNode(ListNode** pHead, int value){    if (pHead == NULL || *pHead == NULL)        return;    ListNode* pToBeDeleted = NULL;    if ((*pHead)->m_nValue == value)    {        pToBeDeleted = *pHead;        *pHead = (*pHead)->m_pNext;    }    else    {        ListNode* pNode = *pHead;        while (pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)            pNode = pNode->m_pNext;        if (pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)        {            pToBeDeleted = pNode->m_pNext;            pNode->m_pNext = pNode->m_pNext->m_pNext;        }    }    if (pToBeDeleted != NULL)    {        delete pToBeDeleted;        pToBeDeleted = NULL;    }}void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted){    if (!pListHead || !pToBeDeleted)        return;    // 要删除的结点不是尾结点    if (pToBeDeleted->m_pNext != NULL)    {        ListNode* pNext = pToBeDeleted->m_pNext;        pToBeDeleted->m_nValue = pNext->m_nValue;        pToBeDeleted->m_pNext = pNext->m_pNext;        delete pNext;        pNext = NULL;    }    // 链表只有一个结点,删除头结点(也是尾结点)    else if (*pListHead == pToBeDeleted)    {        delete pToBeDeleted;        pToBeDeleted = NULL;        *pListHead = NULL;    }    // 链表中有多个结点,删除尾结点    else    {        ListNode* pNode = *pListHead;        while (pNode->m_pNext != pToBeDeleted)        {            pNode = pNode->m_pNext;        }        pNode->m_pNext = NULL;        delete pToBeDeleted;        pToBeDeleted = NULL;    }}// ====================测试代码====================void Test(ListNode* pListHead, ListNode* pNode){    cout << ("The original list is: \n");    PrintList(pListHead);    cout << ("The node to be deleted is: \n");    PrintListNode(pNode);    DeleteNode(&pListHead, pNode);    cout << ("The result list is: \n");    PrintList(pListHead);}// 链表中有多个结点,删除中间的结点void Test1(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    Test(pNode1, pNode3);    DestroyList(pNode1);}// 链表中有多个结点,删除尾结点void Test2(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    Test(pNode1, pNode5);    DestroyList(pNode1);}// 链表中有多个结点,删除头结点void Test3(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    Test(pNode1, pNode1);    DestroyList(pNode1);}// 链表中只有一个结点,删除头结点void Test4(){    ListNode* pNode1 = CreateListNode(1);    Test(pNode1, pNode1);}// 链表为空void Test5(){    Test(NULL, NULL);}int _tmain(int argc, _TCHAR* argv[]){    Test1();    Test2();    Test3();    Test4();    Test5();    return 0;}
0 0