直接free(p),这样行不通,因为我们不能访问其他结点;
如果我们只能访问该结点,可以尝试将该结点的后继结点的数据复制到当前结点,然后删除后继结点
- public static boolean deleteNode (LinkListNode n) {
- if( null == n || null == n.next ) return false;
- LinkListNode next = n.next;
- n.data = next.data;
- n.next = next.next;
- return true;
- }
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结点元素的值。
- //单链表的结点类
- class LNode{
- //为了简化访问单链表,结点中的数据项的访问权限都设为public
- public int data;
- public LNode next;
- }
- public class LinkListUtli {
- public static void deleteNode(LNode p)
- {
- if(p==null||p.next==null) return;//如果p为空或为单链表中最后一个结点不符合题意,直接返回
- LNode q=p.next;//q为p的后继结点
- p.data=q.data;
- p.next=q.next;//从单链表中删除结点q
- }
- }
拓展:如果删除的结点p可能是最后一个结点,怎么办。
解题思路:此时只能保证删除结点的平均时间复杂度为O(1),当p不是最后一个结点,时时间复杂度为O(1),当p是最后一个结点时,时间复杂度为O(n)。
算法实现:
- public class LinkListUtli {
- public static void deleteNode(LNode L,LNode p)
- {
- if(p==null||L==null) return;//如果p为空或单链表L为空不符合题意,直接返回
- if(p.next != null) //如果p不是最后一个结点
- {
- LNode q=p.next;//q为p的后继结点
- p.data=q.data;
- p.next=q.next;//从单链表中删除结点q
- }
- else //如果p是最后一个结点
- {
- LNode pre=L;//用pre表示p的前驱结点
- while(pre.next != null) //保持pre有后继结点
- {
- if(pre.next==p)//如果pre是p的前驱结点
- {
- pre.next=p.next;//将结点p从单链表中删除
- }
- }
- }
- }
- }

542

被折叠的 条评论
为什么被折叠?



