【面试题十三】在O(1)时间删除链表结点

来源:互联网 发布:免费淘宝店标在线制作 编辑:程序博客网 时间:2024/05/23 14:06

在O(1)时间删除链表结点


我们要删除结点i,我们可以把结点i的下一个结点j的内容复制到结点i,然后呢把结点i的指针指向结点j的下一个结点。然后在删除结点j;

1.如果结点i位于链表的尾部;

2.如果结点i位于链表的头部;

3.如果结点i既是链表的头部又是链表的尾部;

DeleNode.cpp:

#include <iostream>#include <cstdio>#include "List.h"using namespace std;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){    printf("The original list is: \n");    PrintList(pListHead);    printf("The node to be deleted is: \n");    PrintListNode(pNode);    DeleteNode(&pListHead, pNode);        printf("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 main(){    Test1();    Test2();    Test3();    Test4();    Test5();    return 0;}


List.h:

#ifndef _List_H_#define _List_H_struct ListNode{    int       m_nValue;    ListNode* m_pNext;};ListNode* CreateListNode(int value);void ConnectListNodes(ListNode* pCurrent, ListNode* pNext);void PrintListNode(ListNode* pNode);void PrintList(ListNode* pHead);void DestroyList(ListNode* pHead);void AddToTail(ListNode** pHead, int value);void RemoveNode(ListNode** pHead, int value);#endif /*_List_H_*/


List.cpp:

#include "List.h"#include <stdio.h>#include <stdlib.h>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)    {        printf("Error to connect two nodes.\n");        exit(1);    }    pCurrent->m_pNext = pNext;}void PrintListNode(ListNode* pNode){     if(pNode == NULL)    {        printf("The node is NULL\n");    }    else    {        printf("The key in node is %d.\n", pNode->m_nValue);    }}void PrintList(ListNode* pHead){    printf("PrintList starts.\n");        ListNode* pNode = pHead;    while(pNode != NULL)    {        printf("%d\t", pNode->m_nValue);        pNode = pNode->m_pNext;    }    printf("\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;    }}


Makefile:

.PHONY:cleanCPP=g++CFLAGS=-Wall -gBIN=testOBJS=DeleNode.o List.oLIBS=$(BIN):$(OBJS)$(CPP) $(CFLAGS) $^ -o $@ $(LIBS)%.o:%.cpp$(CPP) $(CFLAGS) -c $< -o $@clean:rm -f *.o $(BIN)


运行结果:

The original list is: PrintList starts.1       2       3       4       5PrintList ends.The node to be deleted is: The key in node is 3.The result list is: PrintList starts.1       2       4       5PrintList ends.The original list is: PrintList starts.1       2       3       4       5PrintList ends.The node to be deleted is: The key in node is 5.The result list is: PrintList starts.1       2       3       4PrintList ends.The original list is: PrintList starts.1       2       3       4       5PrintList ends.The node to be deleted is: The key in node is 1.The result list is: PrintList starts.2       3       4       5PrintList ends.The original list is: PrintList starts.1PrintList ends.The node to be deleted is: The key in node is 1.The result list is: PrintList starts.PrintList ends.The original list is: PrintList starts.PrintList ends.The node to be deleted is: The node is NULLThe result list is: PrintList starts.PrintList ends.