zoukankan      html  css  js  c++  java
  • 剑指offer-面试题13.在O(1)时间删除链表节点

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

    链表节点与函数的定义如下。

    通常我们删除某个节点都是从头开始遍历到需要删除节点的前一个节点。

    然后使得该节点的next指向删除节点的next即可,这样看来删除一个节点

    的复杂度为O(n)然而我们其实遍历的目的只是想获取想要删除节点的前一

    个节点。

    那么我们可以这样考虑:

    我们把要删除节点下一个节点的值赋值到当前节点,然后将当前节点的下一个

    节点删除即可。

    比如:

    一个链表3->2->5->7->9给定的指针指向5也就是说要删除5这个节点。

    我们将节点5下个节点的值赋值给需要删除的节点即:

    3->2->7->7->9

    然后再p->next=p->next->next即可删除

    代码实现如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     struct ListNode *next;
     6  * };
     7  */
     8 void deleteNode(struct ListNode* node) 
     9 {
    10         if(node==NULL)
    11         return;
    12 
    13     struct ListNode* p,*q;
    14     q=node;
    15     p=node->next;
    16     q->val=p->val;
    17     q->next=p->next;
    18 
    19 }

    勘误:

    上面的方法没有考虑到当要删除的结点是尾结点的情况

    因此当需要删除的结点为尾结点的时候这时候仍需要

    从头遍历到尾结点的前面一个结点。

    但是算法复杂度仍然为1,因为只有一个尾结点需要遍历

    整个链表,复杂度为(O(n)+O(1)*(n-1))/n=O(1)

    代码实现如下:

      1 #include <iostream>
      2 using namespace std;
      3 
      4 /**
      5 * Definition for singly-linked list.
      6 * struct ListNode {
      7 *     int val;
      8 *     struct ListNode *next;
      9 * };
     10 */
     11 struct ListNode 
     12 {
     13     int val;
     14     struct ListNode *next;
     15 };
     16 
     17 ListNode *head;
     18 
     19 void deleteNode(struct ListNode* node) 
     20 {
     21     if(node==NULL)
     22         return;
     23     if(node->next==NULL)
     24     {
     25         ListNode *TempHead;
     26         TempHead=head;
     27         while(TempHead->next->next!=NULL)
     28         {
     29             TempHead=TempHead->next;
     30         }
     31         TempHead->next=NULL;
     32         return;
     33     }
     34 
     35 
     36     struct ListNode *p,*q;
     37     q=node;
     38     p=node->next;
     39     q->val=p->val;
     40     q->next=p->next;    
     41 }
     42 
     43 
     44 ListNode* CreateList()
     45 {
     46     ListNode *Head,*p;
     47     Head=(ListNode*)malloc(sizeof(ListNode));
     48     if(Head==NULL)
     49         return NULL;
     50 
     51     Head->val=0;
     52     Head->next=NULL;
     53     p=Head;
     54     while(true)
     55     {
     56         int data;
     57         cout<<"Please input Node data: ";
     58         cin>>data;
     59         if(data==0)
     60         {
     61             break;
     62         }
     63         else
     64         {
     65             ListNode* NewNode;
     66             NewNode=(ListNode*)malloc(sizeof(ListNode));
     67             NewNode->val=data;
     68             NewNode->next=NULL;
     69             p->next=NewNode;
     70             p=p->next;
     71         }
     72     }
     73 
     74 
     75     return Head->next;
     76 }
     77 
     78 
     79 void PrintList(ListNode* Head)
     80 {
     81     ListNode *p;
     82     p=Head;
     83 
     84     while(p!=NULL)
     85     {
     86         cout<<p->val<<",";
     87         p=p->next;
     88     }
     89 }
     90 
     91 ListNode* GetNodePtr(ListNode* Head)
     92 {
     93     int count;
     94     ListNode* p;
     95     p=Head;
     96     cout<<"Please input the Node Order you want to delete: ";
     97     cin>>count;
     98     int i=0;
     99     while(i<count-1)
    100     {
    101         p=p->next;
    102         i++;
    103     }
    104 
    105     return p;
    106 }
    107 
    108 
    109 int main()
    110 {
    111     ListNode *Node;
    112     head=CreateList();
    113     cout<<"The list is: ";
    114     PrintList(head);
    115     cout<<endl;
    116     Node=GetNodePtr(head);
    117     deleteNode(Node);
    118     cout<<"The delete node list is: ";
    119     PrintList(head);
    120     cout<<endl;
    121     return 0;
    122 } 

    测试结果如下:

    感谢@rainhard指出这个错误

  • 相关阅读:
    解决 Mac launchpad 启动台 Gitter 图标无法删除的问题
    React 与 React-Native 使用同一个 meteor 后台
    解决 React-Native mac 运行报错 error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65. To debug build logs further, consider building your app with Xcode.app, by ope
    一行命令更新所有 npm 依赖包
    swift学习笔记
    IOS语言总结
    focusSNS学习笔记
    别小看锤子,老罗真的很认真
    windowsphone开发页面跳转到另一个dll中的页面
    【令人振奋】【转】微软潘正磊谈DevOps、Visual Studio 2013新功能、.NET未来
  • 原文地址:https://www.cnblogs.com/vpoet/p/4671566.html
Copyright © 2011-2022 走看看