在O(1)时间删除链表结点(Java)

题目:

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:

struct ListNode{
	int m_nValue;
	ListNode* m_pNext;
}
void DeleteNode(ListNode ** pListHead, ListNode* pToBeDeleted);

第一思路:时间复杂度为O(n)的方法

从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。时间复杂度为O(n)。其实这和数组没有什么区别了,没有充分利用链表的特点。

代码实现:

/**
 * 定义单链表的结构体
 * @author Peter
 */
public class ListNode {
	//属性定义成公开的方便调用和使用
	public int data;
	//公有属性
	public ListNode next;
	
}
//O(n)时间复杂度删除pDelNode结点
public void deleteNode1(ListNode pHead, ListNode pDelNode){
	if(pHead==null || pDelNode==null){
		return;
	}
	if(pHead == pDelNode){ //删除的是头结点
		ListNode pNext = pDelNode.next;
		pDelNode.data = pNext.data;
		pDelNode.next = pNext.next;
		return;		
	}
	//利用O(n)的时间复杂度删除结点
	for (ListNode pNode = pHead; pNode.next!=null; pNode = pNode.next) {
		if(pNode.next  == pDelNode){
			pNode.next = pNode.next.next;
			break;
		}
	}
}
第二思路:在O(1)的时间复杂度删除结点

因为从某个链表的结点可以知道链表的下一个结点,故可以把下一结点的内容复制到需要删除的结点上覆盖原有的内容,再把下一个结点删除,就相当于把当前需要删除的结点删除。这是分为三种情况:删除的结点不在链表尾部;链表只有一个结点,删除头结点;链表中有多个结点,删除尾部结点。

代码实现:

//O(1)时间删除链表的结点
public void deleteNode(ListNode pHead, ListNode pDelNode){
	if(pHead==null || pDelNode==null){
		return;
	}
	if(pDelNode.next!=null){ //要删除的结点不是尾部结点
		ListNode pNext = pDelNode.next;
		pDelNode.data = pNext.data;
		pDelNode.next = pNext.next;
	}else if(pHead == pDelNode){ //链表只有一个结点,删除头结点
		pHead = null;
		pDelNode = null;
	}else{ //链表中有多个结点,删除尾结点
		ListNode pNode = pHead;
		while(pNode.next != pDelNode){
			pNode = pNode.next;
		}
		pNode.next = null;
	}
}

时间复杂度分析:

对于n-1个非尾部结点而言删除的时间复杂度为O(1),对于尾部结点删除而言,仍然需要O(n)的时间复杂度。但是平均时间复杂度是:[ ( n - 1 ) * O( 1 ) + O( n ) ] / n,结果还是O(1)。

测试:

public static void main(String[] args) {
	ListNode ln1 = new ListNode();
	ListNode ln2 = new ListNode();
	ListNode ln3 = new ListNode();
	ListNode ln4 = new ListNode();
	ListNode ln5 = new ListNode();
	ListNode ln6 = new ListNode();
	ListNode ln7 = new ListNode();
	ListNode ln8 = new ListNode();
	ln1.next = ln2;
	ln2.next = ln3;
	ln3.next = ln4;
	ln4.next = ln5;
	ln5.next = ln6;
	ln6.next = ln7;
	ln7.next = ln8;
	ln8.next = null;
	ln1.data = 1;
	ln2.data = 2;
	ln3.data = 3;
	ln4.data = 4;
	ln5.data = 5;
	ln6.data = 6;
	ln7.data = 7;
	ln8.data = 8;
		
	Main m1 = new Main();
	m1.deleteNode1(ln1, ln2);
	while(ln1!=null){
		System.out.println(ln1.data);
		ln1 = ln1.next;
	}
}

小结:

考查对链表的认识。

猜你喜欢

转载自blog.csdn.net/u013132035/article/details/80577116
今日推荐