在O时间删除链表结点

Posted 三颗心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在O时间删除链表结点相关的知识,希望对你有一定的参考价值。

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

链表结点与函数的定义如下:

struct ListNode
{
    int            m_nValue;
    ListNode*      m_pNext;
};

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

思路:我们可以很方便的得到要删除的结点的下一结点,如果我们把下一个结点的内容复制到需要删除的结点上覆盖原有的内容,再把下一个结点删除。就相当于把当前需要删除的结点给删除了。

实现代码如下:

  1 #include<iostream>
  2 #include<stdlib.h>
  3 using namespace std;
  4 
  5 //链表结构 
  6 struct ListNode
  7 {
  8     int m_nValue;
  9     ListNode* m_pNext;
 10 };
 11 
 12 //创建一个链表结点 
 13 ListNode* CreateListNode(int value)
 14 {
 15     ListNode *pNode = new ListNode();
 16     pNode->m_nValue=value;
 17     pNode->m_pNext=NULL;
 18     return pNode;
 19     
 20 }
 21 
 22 //遍历链表中所有结点
 23 void PrintList(ListNode* pHead)
 24 {
 25     ListNode *pNode = pHead;
 26     while(pNode!=NULL)
 27     {
 28         cout<<pNode->m_nValue<<" ";
 29         pNode=pNode->m_pNext;
 30     }
 31     cout<<endl;
 32 }
 33 //连接两个结点 
 34 void ConnectListNode(ListNode *pCurrent,ListNode* pNext)
 35 {
 36     if(pCurrent==NULL)
 37     {
 38         cout<<"前一个结点不能为空"<<endl;
 39         exit(1);
 40     }
 41     else
 42     {
 43         pCurrent->m_pNext=pNext;
 44     }
 45 }
 46 
 47 //删除链表 
 48 void DestroyList(ListNode* pHead)
 49 {
 50     ListNode* pNode = pHead;
 51     while(pNode != NULL)
 52     {
 53         pHead = pHead->m_pNext;
 54         delete pNode;
 55         pNode = pHead;
 56     }
 57 }
 58 
 59 
 60 
 61       
 62 //考虑四种不同的情况   
 63 void DeleteNode(ListNode** pListHead, ListNode* pTobeDeleted)
 64 {
 65     if(!pListHead || !pTobeDeleted)
 66         return;
 67     
 68     //要删除的结点不是尾结点 
 69     if(pTobeDeleted->m_pNext != NULL)
 70     {
 71         ListNode* pNext = pTobeDeleted->m_pNext;
 72         pTobeDeleted->m_nValue = pNext->m_nValue;
 73         pTobeDeleted->m_pNext = pNext->m_pNext;
 74 
 75         delete pNext;
 76         pNext = NULL;
 77     }
 78     //链表只有一个结点,删除头结点(也是尾结点) 
 79     else if(*pListHead == pTobeDeleted)
 80     {
 81         delete pTobeDeleted;
 82         pTobeDeleted = NULL;
 83         *pListHead = NULL;
 84     }
 85     //链表中有多个结点,删除尾结点 ,只能遍历链表 
 86     else
 87     {
 88         ListNode* pNode = *pListHead;
 89         while(pNode->m_pNext != pTobeDeleted)
 90         {
 91             pNode = pNode->m_pNext;
 92         }
 93 
 94         pNode->m_pNext = NULL;
 95         delete pTobeDeleted;
 96         pTobeDeleted = NULL;
 97     }
 98 }
 99 
100 int  main()
101 {
102     //创建结点
103     ListNode* pNode1 = CreateListNode(1);
104     ListNode* pNode2 = CreateListNode(2);
105     ListNode* pNode3 = CreateListNode(3);
106     ListNode* pNode4 = CreateListNode(4);
107     ListNode* pNode5 = CreateListNode(5);
108     ListNode* pNode6 = CreateListNode(6);
109     ListNode* pNode7 = CreateListNode(7);
110     //连接结点 
111     ConnectListNode(pNode1,pNode2);
112     ConnectListNode(pNode2,pNode3);
113     ConnectListNode(pNode3,pNode4);
114     ConnectListNode(pNode4,pNode5);
115     ConnectListNode(pNode5,pNode6);
116     ConnectListNode(pNode6,pNode7);
117 
118     PrintList(pNode1);
119     //删除结点 
120     DeleteNode(&pNode1,pNode4);
121     //打印链表 
122     PrintList(pNode1);
123     //删除链表 
124     DestroyList(pNode1);
125     
126     return 0 ;
127 }

运行结果如下:

以上是关于在O时间删除链表结点的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer对答如流系列 - 在O时间删除链表结点

Java 剑指offer(17) 在O时间删除链表结点

在O时间删除链表结点——剑指offer

在O时间删除链表结点

面试题18:在O时间删除链表结点

第六十题(在O时间内删除链表结点)