实现一个算法,删除单链表中间的某个结点,假定你只能访问该结点

直接free(p),这样行不通,因为我们不能访问其他结点;

如果我们只能访问该结点,可以尝试将该结点的后继结点的数据复制到当前结点,然后删除后继结点

 

  1. public static boolean deleteNode (LinkListNode n) {  
  2.     if( null == n || null == n.next ) return false;  
  3.     LinkListNode next = n.next;  
  4.     n.data = next.data;  
  5.     n.next = next.next;  
  6.     return true;  
  7. }  
import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Remove {
    public boolean removeNode(ListNode pNode) {
        // write code here
        if(pNode.next == null){
            return false;
        }else{
            pNode.val = pNode.next.val;
            pNode.next = pNode.next.next;
            return true;
        }
    }
}


但是这样做有一个问题,如果我们要删除的是尾结点,这个算法就失效了,如果是尾结点,可以考虑将这个结点置为假的

 

题目:删除带头结点的单链表L中的结点p,p不是最后一个结点,要求时间复杂度为O(1)。

解题思路:
如果不要求时间复杂度为O(1),我们可以找出p的前驱结点,然后很容易就删除p。

现在要求时间复杂度为O(1),因为p不是最后一个结点,知道结点p我们可以删除p的后继结点,那么我们可以把p的后继结点元素的值赋给p结点元素的值。

 

  1. //单链表的结点类  
  2. class LNode{  
  3.     //为了简化访问单链表,结点中的数据项的访问权限都设为public  
  4.     public int data;  
  5.     public LNode next;  
  6. }  

 

  1. public class LinkListUtli {  
  2.     public static void deleteNode(LNode p)  
  3.     {  
  4.         if(p==null||p.next==null) return;//如果p为空或为单链表中最后一个结点不符合题意,直接返回  
  5.         LNode q=p.next;//q为p的后继结点  
  6.         p.data=q.data;  
  7.         p.next=q.next;//从单链表中删除结点q  
  8.     }  
  9. }  


拓展:如果删除的结点p可能是最后一个结点,怎么办。

解题思路:此时只能保证删除结点的平均时间复杂度为O(1),当p不是最后一个结点,时时间复杂度为O(1),当p是最后一个结点时,时间复杂度为O(n)。

算法实现:

 

  1. public class LinkListUtli {  
  2.     public static void deleteNode(LNode L,LNode p)  
  3.     {  
  4.         if(p==null||L==null) return;//如果p为空或单链表L为空不符合题意,直接返回  
  5.         if(p.next != null) //如果p不是最后一个结点  
  6.         {  
  7.             LNode q=p.next;//q为p的后继结点  
  8.             p.data=q.data;  
  9.             p.next=q.next;//从单链表中删除结点q  
  10.         }  
  11.         else //如果p是最后一个结点  
  12.         {  
  13.             LNode pre=L;//用pre表示p的前驱结点  
  14.             while(pre.next != null) //保持pre有后继结点  
  15.             {  
  16.                 if(pre.next==p)//如果pre是p的前驱结点  
  17.                 {  
  18.                     pre.next=p.next;//将结点p从单链表中删除  
  19.                 }  
  20.             }  
  21.         }  
  22.           
  23.     }  
  24. }

 

 

转载于:https://my.oschina.net/u/2822116/blog/788430

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值