理解Java是如何构造出链表的?
首先要先理解JVM是怎么构建出链表的,JVM里有栈区和堆区,栈区主要存引用,也就是一个指向实际对象的地址,而堆区存的才是创建的对象,例如我们定义这样一个类:
public class LinkedList { private Node head; // 头部节点 private static class Node { // 节点类 int value; Node next; public Node(int value, Node next) { this.value = value; this.next = next; } } }
上述代码中只是声明了一个head的变量,类型为Node类型,如果在LinkedList中new出来一个新Node对象,那么就可以将指向新new出来的Node对象的引用赋值给head,让head指向new出来的新对象,因为head是Node类型,所以head里有两个属性,一个是int类型的value,用来存放值的。另一个是Node类型的next,用于指向下一个对象。之后再new对象就可以用head.next -> new Node了,从而形成链表。
链表增加元素,首部、中间和尾部分别会有什么问题,该如何处理?
三种情况:
1.在头部插入
在头部插入,创建一个新结点newNode,只需newNode.next = head,head = newNode即可。头部插入新节点一定要记得改动head指针,虽说不挪也无伤大雅,但是遍历链表的话,就需要从newNode开始,一般还是用head来表示更好一些。
2.在中间插入
中间插入(如下图)
如果要在7的前面插入,当cur.next=node(7)了就应该停下来,此时cur.val=15。然后需要给newNode前后接两根线,此时只能先让new.next=node(15).next(图中虚线),然后node(15).next=new,而且顺序还不能错。
不要颠倒顺序,如果颠倒顺序,new出来的节点的next指向的就是自己了,就与node(7)断开了
3.在尾部插入
表尾插入就比较容易了,只要将尾结点指向新结点就行了。
3.链表删除元素,首部、中间和尾部分别会有什么问题,该如何处理?
三种情况:
1.在首部删除
只要执行head=head.next就行了。如下图,将head向前移动一次之后,原来的结点不可达,会被JVM回收掉。
2.在中间删除
删除中间结点时,也会要用cur.next来比较,找到位置后,将cur.next指针的值更新为cur.next.next就可以解决,如下图所示:
3.在尾部删除
删除的过程不算复杂,也是找到要删除的结点的前驱结点,这里同样要在提前一个位置判断,例如下图中删除40,其前驱结点为7。遍历的时候需要判断cur.next是否为40,如果是,则只要执行cur.next=null即可,此时结点40变得不可达,最终会被JVM回收掉。