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

题目:给定单向链表的头指针和一个结点指针,定义一个函数在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 }

运行结果如下:

时间: 2024-10-12 13:12:07

在O(1)时间删除链表结点的相关文章

面试题18(一):在O(1)时间删除链表结点

// 面试题18(一):在O(1)时间删除链表结点 // 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该 // 结点.链表结点与函数的定义如下: // struct ListNode{ // int m_nValue; // ListNode* m_pNext; // }; // void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted); 解题思路: 这是目前为止,唯一一道,我不看书就知道怎么做的题. 正

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

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 思路 通常那样从头开始查找删除需要的时间为O(n),要在O(1)时间删除某结点,可以这样实现:设待删除结点i的下一个结点为j,把j的值复制到i,再把i的指针指向j的下一个结点,最后删除j,效果就相当于删除j. 注意特殊情况:1.当待删除结点i为尾结点时,无下一个结点,则只能从头到尾顺序遍历:2.当链

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

面试题17:在O(1)时间删除链表结点 问题描述 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 链表结构 public class Node{ int val; Node next; public Node(int value,Node next) { val=value; next=next; } } 问题分析 曾经未碰到这道题之前,删除链表的节点,用的方法非常原始.基础(代码如下),很明显这种原始的方式带来的时间复杂度为O(n) //从链表中删除index(0~

《剑指offer》第十八题:在O(1)时间删除链表结点

// 面试题18(一):在O(1)时间删除链表结点 // 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该 // 结点. #include <cstdio> #include "List.h" void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted) { if (pListHead == nullptr || pToBeDeleted == nullptr) return; //多个

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

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 因为要求时间复杂度为O(1),所以肯定不能遍历链表,那样的话时间复杂度就是O(N)了:可以想到,其实要求删除该结点,真正的目的并不是要将结点的数据包括结点所占的内存都给删除,只是想让数据消失就可以了,至于结点,除去任意一个结点所占的空间都是OK的: 所以,这里换一种思路,若要删除指定的结点,一般需要将前一个结点的next指针指向要删除结点的下一个结点,这样要删除的结点就可以脱离链表而被删除了,但这里关键就是即是单链表没有

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

http://zhedahht.blog.163.com/blog/static/254111742007112255248202/ 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 函数的声明如下: void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted); 分析:这是一道广为流传的Googl

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

题目:在给定单链表的头结点指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 代码: 1 #include <stdio.h> 2 #include "malloc.h" 3 struct ListNode 4 { 5 int value; 6 ListNode *next; 7 }; 8 //尾插法创建链表 9 ListNode *createList() 10 { 11 ListNode *H = (ListNode *)malloc(sizeof(ListNo

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

题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: typedef struct ListNode { int val; struct ListNode *p_next; }NODE, *PNODE; void delete_node(PNODE *pListHead, PNODE pToDeleted); 一般来说,我们拿到一个删除链表的某个结点的题目,最常规的解法无疑是从链表的头结点开始顺序遍历,依次查找要删除的结点,找到被删除结点的前

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

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数定义如下: struct ListNode { int m_nValue; ListNode* m_pNext; }; code: //把待删结点后面一个结点的值赋给待删结点,然后把待删结点next指针指向下下个结点,然后删除下个结点, 达到和删除待删结点一样的效果. void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted) { if (!pL