【面试题013】在O(1)时间删除链表结点
我们要删除结点i,我们可以把结点i的下一个结点j的内容复制到结点i,然后呢把结点i的指针指向结点j的下一个结点。然后在删除结点j。
1.如果结点i位于链表的尾部;
2.如果结点i位于链表的头部;
3.如果结点i既是链表的头部又是链表的尾部;
DeleNode.cpp:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
#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; } } // 链表中有多个结点,删除中间的结点 int main() { 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); ListNode *pListHead = pNode1; ListNode *pNode = pNode3; printf("The original list is: "); PrintList(pListHead); printf("The node to be deleted is: "); PrintListNode(pNode); DeleteNode(&pListHead, pNode); printf("The result list is: "); PrintList(pListHead); DestroyList(pNode1); return 0; } |
运行结果:
The original list is:
PrintList starts.
1 2 3 4 5
PrintList ends.
The node to be deleted is:
The key in node is 3.
The result list is:
PrintList starts.
1 2 4 5
PrintList ends.
List.h:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#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:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
#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. "); exit(1); } pCurrent->m_pNext = pNext; } void PrintListNode(ListNode *pNode) { if(pNode == NULL) { printf("The node is NULL "); } else { printf("The key in node is %d. ", pNode->m_nValue); } } void PrintList(ListNode *pHead) { printf("PrintList starts. "); ListNode *pNode = pHead; while(pNode != NULL) { printf("%d ", pNode->m_nValue); pNode = pNode->m_pNext; } printf(" PrintList ends. "); } 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:
1
2 3 4 5 6 7 8 9 10 11 12 |
.PHONY:clean
CPP=g++ CFLAGS=-Wall -g BIN=test OBJS=DeleNode.o List.o LIBS= $(BIN):$(OBJS) $(CPP) $(CFLAGS) $^ -o $@ $(LIBS) %.o:%.cpp $(CPP) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(BIN) |