zoukankan      html  css  js  c++  java
  • 《剑指offer》面试题13—O(1)时间删除链表结点

    题目:给定单向链表的头指针和某结点指针,实现函数在O(1)时间内删除指定节点。

    思路:由于没有要删除结点(j结点)的前一个结点(i结点)指针,通常想法是从头开始遍历找到指定结点的前一个结点(i结点),然后使i结点的指针指向j结点的后一个结点k结点。但是这样是O(n)的时间复杂度,不符合要求。

    解决方法很巧妙:由于有要删除的j结点的指针,因此可以很容易得到j结点的后一个结点k结点的指针,只要把k结点的内容复制给i结点,然后删除k结点即可。

    但是要注意!如果链表只有一个结点,head指针要指NULL;如果要删除的是尾结点,即后面没有结点了,那么也只能从头开始遍历。

      1 #include <iostream>
      2 using namespace std;
      3 
      4 
      5 class Node
      6 {
      7 public:
      8     Node(int v, Node* n)
      9     {val = v;
     10     next = n;}
     11     ~Node(){}
     12     int val;
     13     Node* next;
     14 };
     15 Node * phead = NULL;
     16 
     17 void AddNode(int val)
     18 {
     19     Node* pnode = new Node(val,NULL);
     20     //Node one_node(val,NULL); 这里有大bug!如果这样写,在函数退出时自动调用析构函数!链表就乱了!
     21     if(phead == NULL)
     22     {
     23         phead = pnode;
     24     }
     25     else
     26     {
     27         Node* p = phead;
     28         while(p->next != NULL)
     29         {
     30             p = p->next;
     31         }
     32         p->next = pnode;
     33     }
     34 }
     35 void PrintLink()
     36 {
     37     Node* p = phead;
     38     while(p != NULL)
     39     {
     40         int temp = p->val;
     41         cout<<temp<<endl;
     42         p = p->next;
     43     }
     44 }
     45 void DeleteNode(Node* pdelete)
     46 {
     47     Node * p;
     48     if(phead == NULL || pdelete == NULL)   //check
     49         return;
     50 
     51     if(pdelete == phead)  //the node to be deleted is equal to the head
     52     {
     53         if(phead->next == NULL)//only one node
     54         {
     55             delete pdelete;
     56             pdelete = NULL;
     57             phead = NULL;
     58         }
     59         else        //more than one node
     60         {
     61             phead = phead->next;
     62             delete pdelete;
     63             pdelete = NULL;
     64         }
     65     }
     66     else if(pdelete->next == NULL) //the node to be deleted is the last node
     67     {
     68         p = phead;
     69         while (p->next->next != NULL) p = p->next;  //find the node before the last node
     70         p->next = NULL;
     71         delete pdelete;
     72         pdelete = NULL;
     73     }
     74     else //the normal situation,not the head or the tail
     75     {
     76         Node* pnext = pdelete->next;
     77         pdelete->val = pnext->val;
     78         pdelete->next = pnext->next;
     79         delete pnext;
     80         pnext = NULL;
     81     }
     82 }
     83 
     84 int main()
     85 {
     86     int val,del,flag;
     87     Node* pdelete;
     88     cin>>val;
     89     while(val != 0)
     90     {
     91         AddNode(val);
     92         cin>>val;
     93     }
     94     PrintLink();
     95 
     96     cout<<"Input the node number you want to delete:"<<endl;
     97     cin>>del;
     98 
     99     pdelete = phead;
    100     if(phead == NULL) cout<<"No node!"<<endl;
    101 
    102     flag = 1;
    103     for(int i=0;i<del&&flag;i++)
    104     {
    105         if (pdelete->next!=NULL) pdelete = pdelete->next;
    106         else
    107         {
    108             cout << "The node not exists!"<<endl;
    109             flag=0;
    110         }
    111     }
    112     if(flag) DeleteNode(pdelete);
    113     PrintLink();
    114 
    115     return 0;
    116 }
    View Code

       

  • 相关阅读:
    cxgrid动态创建列
    cxgrid显示海量数据
    Delphi 两个应用程序(进程)之间的通信
    Delphi实现窗体内嵌其他应用程序窗体
    Change tab position of PageControl to bottom
    how can I make the login form transparent?
    UniDBGrid增加显示记录数的label及隐藏refresh按钮
    java工厂模式实例化class
    Java 语言细节
    applet示例 WelcomeApplet.java <Core Java>
  • 原文地址:https://www.cnblogs.com/CnZyy/p/3307847.html
Copyright © 2011-2022 走看看