18. 刪除鏈表中的節點
問題描述
給定單向鏈表的頭指針和一個節點指針,定義一個函數在O(1)時間刪除該節點。
單向鏈表的定義如下:
class ListNode{
int m_nValue;
ListNode next;
public ListNode() {
this.next = null;
}
}
分析
在O(1)的時間內,我們要刪除一個節點的話,如果我們遍歷鏈表找到這個節點的話,這需要O(n)的時間,所以我們可以另闢蹊徑,刪除它的下一個節點,把它的下一個節點的內容複製到這個節點內。
這個思想,需要考慮到,我們刪除的是否是尾節點,尾節點的話,另做考慮,我們不能用這種方法解決。
n個節點的鏈表中,刪除中間節點(包括頭節點,n > 1)
deleteNode.data = deleteNode.next.data;
deleteNode.next = deleteNode.next.next;
deleteNode.next = null;
如果是尾節點的話,刪除尾節點的方法
ListNode pNode = listHead;
while(pNode.next != deleteNode){
pNode = pNode.next;
}
pNode.next = null;
如果只有一個節點,要刪除這個節點的話,通過函數我們實現起來,可能有點困難
我們可以使用頭結點,利用頭節點來操作,這個我只是提一下,不附代碼
我們可以通過函數返回值來實現
我嘗試調用gc來回收這個對象,但是成功不了
代碼上的這個部分是實現不了的,可以借鑑下,在C和C++中有指針的說法,我們free指針就可以做到了
代碼如下:
import java.awt.*;
/**
* Class day19 ...
*
* @author LiJun
* Created on 2019/1/22
*/
public class day18 {
private static class ListNode{
int m_nValue;
ListNode next;
public ListNode() {
this.next = null;
}
}
private static void deleteNode(ListNode listHead, ListNode pToDeleted){
if(pToDeleted == null || listHead == null){
return;
}
// 先判斷要刪除的節點是不是尾節點,如果不是就刪除節點
if(pToDeleted.next != null){
pToDeleted.m_nValue = pToDeleted.next.m_nValue;
pToDeleted.next = pToDeleted.next.next;
}
// 判斷鏈表中的節點是不是隻有一個
else if(listHead == pToDeleted){
// 供參考,實現不了的,這裏只是提供思路,C和C++中可行,指針
listHead = pToDeleted = null;
}
// 鏈表中有多個節點,刪除尾節點
else {
ListNode pNode = listHead;
while(pNode.next != pToDeleted){
pNode = pNode.next;
}
pNode.next = null;
}
}
private static void print(ListNode node){
while(node != null){
System.out.print(node.m_nValue + " ");
node = node.next;
}
System.out.println();
}
public static void main(String[] args) {
ListNode node1 = new ListNode();
ListNode node2 = new ListNode();
ListNode node3 = new ListNode();
ListNode node4 = new ListNode();
ListNode node5 = new ListNode();
ListNode node6 = new ListNode();
ListNode node7 = new ListNode();
ListNode node8 = new ListNode();
node1.m_nValue = 1;node1.next = node2;
node2.m_nValue = 2;node2.next = node3;
node3.m_nValue = 3;node3.next = node4;
node4.m_nValue = 4;node4.next = node5;
node5.m_nValue = 5;node5.next = node6;
node6.m_nValue = 6;node6.next = node7;
node7.m_nValue = 7;node7.next = node8;
node8.m_nValue = 8;
print(node1);
// 刪除頭結點
deleteNode(node1, node1);
print(node1);
// 刪除中間節點
deleteNode(node1, node3);
print(node1);
// 刪除尾節點
deleteNode(node1,node8);
print(node1);
// 只有一個節點且刪除 目前不成立
ListNode node9 = new ListNode();
node9.m_nValue = 9;
deleteNode(node9, node9);
node9 = null;
print(node9);
}
}