剑指Offer 面试题18:删除链表节点 Java代码实现

来源:互联网 发布:tm域名有必要注册吗 编辑:程序博客网 时间:2024/06/05 14:48

题目:在O(1)时间内删除链表节点。

给定单向链表头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。


这儿采用有头结点的单链表结构,头结点的存在是为了方便操作,针对单链表来说,如果带头结点的话,头指针指向头结点,头结点指向首结点;如果不带头结点的话,头指针指向首结点,如果进行插入和删除操作,必须要注意是否是在链表头进行,要分情况处理,而带头结点的不用分情况,比较方便。


一般情况下,删除单链表中的第k个节点,需要遍历链表找到对应节点的上一节点,然后删除第k个节点,这样的时间复杂度自然是O(n)。这儿情况比较特殊,方法参数给了我们需要删除的节点引用,就可以采用一种新的思路删除该节点。具体而言,就是把待删除节点的下一节点数据域复制到待删除节点,然后删除下一节点。整个过程实际上就是删除了待删除节点的内容,时间复杂度为O(1)。当然,尾节点没有下一节点,我们还是需要遍历,不过平均复杂度仍然是O(1)。

节点类代码如下,就是一个value域,一个next域。里面的函数是打印输出链表,方便看结果。

public class ListNode {int value;ListNode next;public static void printStr(ListNode head) {if (head == null)return;ListNode pNode = head.next;while (pNode != null) {if(pNode.next==null){System.out.print(pNode.value);System.out.println();pNode = pNode.next;}else{System.out.print(pNode.value);System.out.print("->");pNode = pNode.next;}}}}

主要方法代码:

public static void deleteNode(ListNode pHead,ListNode toBeDelete){if(pHead==null||toBeDelete==null)return;//要删除的节点不是尾节点if(toBeDelete.next!=null){ListNode pNext=toBeDelete.next;toBeDelete.value=pNext.value;toBeDelete.next=pNext.next;pNext=null;}else if(pHead==toBeDelete){//链表只有一个节点pHead=null;}else{//链表有多个节点,要删除尾节点//只有这种情况下时间复杂度为O(n)ListNode pNode=pHead;while(pNode.next!=toBeDelete){pNode=pNode.next;}pNode.next=null;toBeDelete=null;}}

上面代码中必须要求我们输入的参数,节点toBeDelete必须在链表中。受限于O(1)的要求,这儿没有做检查。

测试代码如下:

public static void main(String[] args) {ListNode head = new ListNode();ListNode node1 = new ListNode();ListNode node2 = new ListNode();ListNode node3 = new ListNode();ListNode node4 = new ListNode();//采有头结点的链表,数据域不用,指针域指向第一个有数据的链表节点head.next = node1;node1.value = 1;node1.next = node2;node2.value = 2;node2.next = node3;node3.value = 3;node3.next = node4;node4.value=4;node4.next = null;ListNode.printStr(head);//deleteNode(head, node1);//deleteNode(head, node4);deleteNode(head, node2);ListNode.printStr(head);}
输出如下:

1->2->3->4
1->3->4

阅读全文
0 0
原创粉丝点击