在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(ListNode));
 12     H->next = NULL;
 13     ListNode *s, *r = H; //r指向尾节点,s为要插入的结点
 14     int x;
 15     scanf_s("%d",&x);
 16     while (x!=-1)
 17     {
 18         s = (ListNode *)malloc(sizeof(ListNode));
 19         s->value = x;
 20         s->next = r->next;
 21         r->next = s;
 22         r = s;
 23         scanf_s("%d", &x);
 24     }
 25     return H;
 26 }
 27 void DeleteNode(ListNode **pListHead,ListNode *pToDelete)
 28 {
 29     if (pListHead == NULL || *pListHead == NULL || pToDelete == NULL)
 30         return;
 31     //要删除的结点不是尾结点,将需要删除的结点后面的结点覆盖到要删除的结点,将后面的结点删除
 32     if (pToDelete->next != NULL)
 33     {
 34         ListNode *pNode = pToDelete->next;
 35         pToDelete->value = pNode->value;
 36         pToDelete->next = pNode->next;
 37         delete pNode;
 38         pNode = NULL;
 39     }
 40     //链表中只有一个结点,删除头结点(也是尾结点)
 41     else if (*pListHead == pToDelete)
 42     {
 43         delete pToDelete;
 44         pToDelete = NULL;
 45         pListHead = NULL;
 46     }
 47     //链表中有多个结点,要删除的结点在尾部,需要找到删除结点的前一个结点(常规方法)
 48     else
 49     {
 50         ListNode *pNodes = *pListHead;
 51         while (pNodes->next != pToDelete)
 52         {
 53             pNodes = pNodes->next;
 54         }
 55         pNodes->next = NULL;
 56         delete pToDelete;
 57         pToDelete = NULL;
 58     }
 59 }
 60 ListNode *find(ListNode *list, int x)
 61 {
 62     ListNode *fq;
 63     fq = list->next;
 64     if (fq == NULL)
 65         return NULL;
 66     while (fq != NULL)
 67     {
 68         if (fq->value == x)
 69             return fq;
 70         fq = fq->next;
 71     }
 72     return NULL;
 73 }
 74
 75 int main()
 76 {
 77     int x;
 78     ListNode *p,*q;
 79     ListNode *H = (ListNode *)malloc(sizeof(ListNode));
 80     printf("输入单链表的结点值,以-1结束:");
 81     H = createList();
 82     printf("输入要删除的结点的值:");
 83     scanf_s("%d",&x);
 84     q = find(H,x);
 85     DeleteNode(&H,q);
 86     p = H->next;
 87     printf("删除一个结点%d后的值为 :",x);
 88     while (p != NULL)
 89     {
 90         printf("%3d",p->value);
 91         p = p->next;
 92     }
 93     printf("\n");
 94
 95     return 0;
 96 }
 97
 98 /*
 99 输入单链表的结点值,以-1结束:1 2 3 4 5 6 -1
100 输入要删除的结点的值:1
101 删除一个结点1后的值为 :  2  3  4  5  6
102 请按任意键继续. . .
103
104 输入单链表的结点值,以-1结束:1 2 3 4 5 6 -1
105 输入要删除的结点的值:3
106 删除一个结点3后的值为 :  1  2  4  5  6
107 请按任意键继续. . .
108
109 输入单链表的结点值,以-1结束:1 2 3 4 5 6 -1
110 输入要删除的结点的值:6
111 删除一个结点6后的值为 :  1  2  3  4  5
112 请按任意键继续. . .
113 */

时间: 2024-10-04 09:23:24

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

【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; //多个

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

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

LeetCode | 面试题06. 从尾到头打印链表【剑指Offer】【Python】

LeetCode 面试题06. 从尾到头打印链表[剑指Offer][Easy][Python][链表] 问题 力扣 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000 思路 解法一 reverse函数 时间复杂度: O(n),n为 head 链表长度. 空间复杂度: O(n),n为 head 链表长度. Python3代码 # Definition for si

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

题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 链表结点与函数的定义如下: struct ListNode { int m_nValue; ListNode* m_pNext; }; void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted); 思路:我们可以很方便的得到要删除的结点的下一结点,如果我们把下一个结点的内容复制到需要删除的结点上覆盖原有的内容,再把下一个结点删除.就相当于把当前需要删除的

在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)时间删除链表结点

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