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指出这个错误

  • 相关阅读:
    其实php真的不错!!!
    mysql 中 时间和日期函数
    mysql grant 命令三种常用
    "设备用反线 不同设备用平行" 这条法则要好好理解.
    mysql 用户管理
    discuz! 页面含义及目录结构分析(转)
    Html TO Ubb and Ubb TO Html
    zend Development Environment 5.5 6.0 6.1 注册码
    discuz登陆相关资料
    linux中的定制任务 crontab
  • 原文地址:https://www.cnblogs.com/vpoet/p/4671566.html
Copyright © 2011-2022 走看看