`

java-60-在O(1)时间删除链表结点

 
阅读更多

public class DeleteNode_O1_Time {

	/**
	 * Q 60 在O(1)时间删除链表结点
	 * 给定链表的头指针和一个结点指针(!!),在O(1)时间删除该结点
	 * 
	 * Assume the list is:
	 * head->...->nodeToDelete->mNode->nNode->...->tail
	 * you have already the point of 'nodeToDelete' in hand.So what you need to do is:
	 * 1.copy the data of 'mNode' to 'nodeToDelete'
	 * 2.nodeToDelete.next=nNode;
	 * However,when deleting the last node,you have to iterate from 'head'.No shortcut.
	 * 
	 * ---public static void deleteNode(Node head,Node nodeToDelete){
	 * cannot do it like that.Because you cannot set head=null to make 'list' empty.
	 * see 'class ParameterTransfer'
	 */
	public static void deleteNode(List list,Node nodeToDelete){
		Node head=list.head;
		if(head==null||nodeToDelete==null){
			return;
		}
		if(head.next==null&&nodeToDelete==head){//Only one node in list and you happen to delete the node.
			list.head=null;//head=null;-->wrong
			return;
		}
		Node node=head;
		if(node.next!=null&&nodeToDelete!=null){
			Node mNode=nodeToDelete.next;
			if(mNode!=null){
				Node nNode=mNode.next;
				nodeToDelete.data=mNode.data;
				nodeToDelete.next=nNode;
			}else {//'nodeToDelete' is the last Node.
				Node previous=node;
				while(node.next!=null){
					previous=node;
					node=node.next;
				}
				previous.next=null;
				return;
			}
			
		}
	}
	private static class List{
		private Node head;
		
		Node createList(int[] data){
			if(data==null||data.length==0){
				return null;
			}
			Node previous=null;
			for(int len=data.length,i=len-1;i>=0;i--){
				head=new Node(data[i]);
				head.next=previous;
				previous=head;
			}
			return head;
		}
		void printList(){
			Node node=head;//don't use 'head' immediately.It wastes my time to find the bug...
			while(node!=null){
				System.out.print(node.data+" ");
				node=node.next;
			}
			System.out.println();
		}
		Node getNodeAt(int pos){//starts from 0
			Node re=null;
			int index=0;
			Node node=head;
			while(node!=null){
				if(index==pos){
					return node;
				}
				node=node.next;
				index++;
			}
			return re;
		}
	}
	private static class Node{
		int data;
		Node next;
		Node(int data){
			this.data=data;
		}
	}
	
	public static void main(String[] args) {
		int[] data={0,1,2,3,4,5,6,7,8};
		List list=new List();
		list.createList(data);
		list.printList();
		
		Node nodeToDelete=list.getNodeAt(8);
		deleteNode(list,nodeToDelete);
		
		nodeToDelete=list.getNodeAt(3);
		deleteNode(list,nodeToDelete);
		
		nodeToDelete=list.getNodeAt(0);
		deleteNode(list,nodeToDelete);
		
		list.printList();//1 2 4 5 6 7
		
		list.createList(new int[]{1});
		deleteNode(list,list.getNodeAt(0));
		list.printList();//nothing.
		
	}
}




public class ParameterTransfer {

	/**
	 * 1.primitive type: pass by value
	 * 2.reference type: you can change the paremeter's status,but you cannot set it null.
	 */
	public static void main(String[] args) {
		ParameterTransfer p = new ParameterTransfer();
		TestData test = new TestData(1);
		p.setNull(test);
		System.out.println(test == null);// false--cannot set it null
		p.changeReference(test);
		System.out.println(test.i);//1--cannot change reference
		p.changeData(test);
		System.out.println(test.i);// 2--change its status
		
	}

	public void changeData(TestData test){
		test.i=2;
	}
	public void setNull(TestData test) {
		test = null;
		return;
	}
	
	public void changeReference(TestData test) {
		TestData test2=new TestData(2);
		test = test2;
		return;
	}
}

class TestData {
	int i;

	TestData(int i) {
		this.i = i;
	}
}
分享到:
评论

相关推荐

    删除链表的倒数第 N 个结点(java代码).docx

    通过上述方法,我们可以在 O(n) 的时间复杂度内找到并删除链表的倒数第 N 个结点。这种方法避免了两次遍历链表的过程,从而提高了算法的效率。快慢指针技巧在处理链表问题时非常实用,尤其是在需要找到特定位置的...

    java-leetcode题解之第147题对链表进行插入排序.zip

    - 算法设计和分析,包括复杂度评估(时间复杂度为O(n^2),空间复杂度为O(1))。 通过解决这个问题,你可以提升自己的链表操作技巧,增强对排序算法的理解,同时锻炼到实际编程能力。在LeetCode上完成这类题目,对于...

    java面试-leetcode面试题解之第19题删除链表的倒数第N个结点.zip

    1. 时间复杂度和空间复杂度分析:此算法的时间复杂度为O(N),因为每个节点最多被访问两次。空间复杂度为O(1),因为我们只使用了常数级别的额外空间。 2. 边界条件处理:如链表为空、N为0、N大于链表长度等特殊情况。...

    2009计算机考研题:查找链表中倒数第k个结点

    这将使得时间复杂度降低到O(1),但会增加空间复杂度。 总结一下,查找链表中倒数第k个节点的问题主要考察了对链表数据结构的理解和操作,以及双指针算法的应用。`MyLinkList.java`文件中的实现可能包括了链表节点和...

    学生信息管理系统---链表实现

    由于链表没有像数组那样提供随机访问的能力,所以查找效率取决于链表的长度,时间复杂度为O(n)。 更新操作涉及到找到目标节点,修改其数据域,然后返回。同样,删除操作需要找到待删除节点,将其前一个节点的next...

    0基础学数数据结构--链表

    - **链表**:相比之下,链表在插入或删除元素时只需修改相邻结点的指针即可完成操作,无需移动元素,效率更高。 #### 五、单链表 单链表是最简单的链表形式,其中每个结点包含一个指向下一个结点的指针。 - **...

    java代码-查找链表头结点

    在Java中,我们通常会创建一个`Node`类来表示链表节点,并定义一个`LinkedList`类来管理链表的操作,如插入、删除和查找节点。以下是关于查找链表头结点的详细知识点: 1. **链表的定义**: - 链表由一系列节点...

    Java用数组和链表的方式简单实现HashMap的增删改功能 数组和链表.pdf

    红黑树是一种自平衡二叉查找树,它可以在O(log n)时间内进行查找、插入和删除操作。红黑树的每个节点都包含一个键值对,并且节点的颜色只能是红色或黑色。红黑树的特点是: * 每个节点都是红色或黑色。 * 根节点是...

    实战应用Java算法分析与设计(链表、二叉树、哈夫曼树、图、动态规划)视频

    通过旋转操作保持树的平衡状态,从而保证了查找、插入和删除操作的时间复杂度为O(logn)。 #### 四、哈夫曼树 **1. 哈夫曼树定义** 哈夫曼树也称最优二叉树,是一种带权路径长度最短的二叉树,常用于数据压缩。其...

    8.顺序表和链表1

    链表的主要优势在于插入和删除操作,特别是对于表头和中间位置的操作,其时间复杂度通常为O(1),但访问元素的速度比顺序表慢,因为需要遍历指针。链表有多种类型,包括单向链表、双向链表、带头结点和不带头结点的...

    [宫水三叶的刷题日记]:链表1

    时间复杂度为O(max(m, n)),其中m和n分别是两个输入链表的长度,因为我们需要遍历最远到达的位置。空间复杂度主要取决于创建的新节点,为O(max(m, n))(忽略常数项)。 接下来,我们讨论“删除链表的倒数第n个节点...

    编写一个将二叉树中每个结点的左右孩子交换的算法。

    - **时间复杂度**:该算法的时间复杂度为 O(n),其中 n 是二叉树中节点的数量。因为每个节点只被访问一次。 - **空间复杂度**:由于使用了递归,因此空间复杂度主要取决于递归栈的深度,最坏情况下为 O(h),h 是树的...

    java数据结构与算法

    - 链式存储适合于插入和删除操作,时间复杂度为O(1)。 - **基于空间的比较** - 顺序存储需要预先分配固定大小的空间。 - 链式存储按需分配空间,但每个节点需要额外的指针空间。 **3.5 链接表** - **基于结点的...

    职工信息链表文件版

    总的来说,"职工信息链表文件版"项目涉及到C++中的链表和向量数据结构,以及文件I/O操作。通过这些知识,我们可以实现对职工信息的有效管理和持久化存储,同时利用向量的便利性进行数据处理。在实际开发中,还需要...

Global site tag (gtag.js) - Google Analytics