您的位置:首页 > Web前端

剑指Offer:在O(1)时间内删除链表结点

2018-01-30 20:00 302 查看
题目:给定单向链表和一个指定的结点,定义一个函数在O(1)时间删除该结点。

在以往的删除结点中我们所用的方法是从头结点开始一个个的遍历到指点结点的前一个结点再进行删除,因为我们无法通过当前结点找到前一个结点,这种方法的时间复杂度为O(n)。

现在摆在我们面前的一个问题就是我们是不是一定要得到删除结点的前一个结点呢?答案是否定的。我们应该换一种思路进行删除:将要删除结点的下一个结点的数据都复制到要删除结点中,然后再删除下一个结点。这样子我们不是也“删除”了指定结点嘛!

要注意的坑:

如果要删除尾结点呢?它没有下一个结点呀!

删除尾结点这个只能按照以往的方法一个个的遍历到前一个结点进行删除了。

如果链表只有一个结点那么头结点也是尾结点,删除完后还要讲头结点置为null

Java代码实现:

单链表的创建参见【链表】

private static void DeleteNode(SingleLinkList list,LinkNode deleteNode){
if(list==null||deleteNode==null){
return;
}
//要删除的结点不是尾结点
if(deleteNode.getNext()!=null){
deleteNode.setIdata(deleteNode.getNext().getIdata());//将下一个结点的值复制给要删除的结点
deleteNode.setNext(deleteNode.getNext().getNext());//删除下一个结点
}else{
//如果要删除的结点既是首结点和尾结点,即链表只有一个结点
if(list.getHead()==deleteNode){
list.setHead(null);
}else{
LinkNode previous = list.getHead();
LinkNode current = list.getHead();
while(current!=deleteNode){
previous = current;
current = current.getNext();
}
previous.setNext(null);
}
}
}


测试代码:

public static void main(String[] args) {
LinkNode node1 = new LinkNode(10);
LinkNode node2 = new LinkNode(15);
LinkNode node3 = new LinkNode(12);
LinkNode node4 = new LinkNode(5);
LinkNode node5 = new LinkNode(4);
SingleLinkList list = new SingleLinkList();
list.insertHead(node1);
list.insertHead(node2);
list.insertHead(node3);
list.insertHead(node4);
list.insertHead(node5);
list.displayList();

DeleteNode(list, node3);//删除非尾结点
list.displayList();
DeleteNode(list,node1);//删除尾结点
list.displayList();

SingleLinkList list2 = new SingleLinkList();
LinkNode node = new LinkNode(100);
list2.insertHead(node);
list2.displayList();
DeleteNode(list2,node);//链表元素只有一个,删除尾结点
list2.displayList();
}


测试结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息