理解Java是如何构造出链表的
链表是一种常见的数据结构,由一系列的节点组成。每个节点都包含一个数据元素和一个指向下一个节点的引用。通过这种方式,每个节点都与链表中的下一个节点连接起来,从而形成了链表的结构。
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
// 这个作用不大,写了更加规范
next = null;
}
/**
* 符合面向对象的要求,但可以精简舍去
**/
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode next) {
this.next = next;
}
public static void main(String[] args) {
ListNode listnode = new ListNode(1);
System.out.println("当前节点的值:" + listnode.val);
System.out.println("下一个节点:" + listnode.next);
}
}
ListNode类包含一个整型数据val和一个指向下一个节点的引用next。通过这种方式,每个节点都可以连接起来,形成一个链表的结构。
链表增加元素,首部、中间和尾部分别会有什么问题,该如何处理?
表头插入
-
创建一个新节点 newNode
-
将新结点的下一个节点指向链表原来的头节点
返回的时候,需要重新指向表头。
中间插入
-
创建一个新节点 newNode
-
找到插入的位置position前一个节点
-
新节点指向“插入的位置前一个节点”对应的下一个节点。newNode.next = node(position).next
-
“插入的位置前一个节点”指向新节点node(position).next = newNode
必须在插入位置的前一个位置停下来,让新节点获取它的next,然后在将它指向新节点。顺序反了会丢失后继节点。
结尾插入节点
-
创建一个新节点 newNode
-
将尾节点指向新节点
/**
* 插入
*
* @param head 头节点
* @param nodeInsert 待插入的节点
* @param position 待插入的位置
* @return 插入后得到的链表头节点
*/
public static Node insertNode(Node head, Node nodeInsert, int position) {
// 为空返回
if (head == null) {
return nodeInsert;
}
// 越界判断
int size = length(head);
if (position > size + 1 || position < 1) {
System.out.println("位置参数越界");
return head;
}
// 在链表开头插入
if (position == 1) {
nodeInsert.next = head;
// return nodeInsert;直接返回新的头节点
head = nodeInsert;
return head;
}
Node pNode = head;
int count = 1;
while (count < position - 1) {
pNode = pNode.next;
count++;
}
// 插入值先指向null,插入前的位置指向插入值
nodeInsert.next = pNode.next;
pNode.next = nodeInsert;
return head;
}
链表删除元素,首部、中间和尾部分别会有什么问题,该如何处理?
删除表头结点
-
将第二个结点设置成头节点,执行head =head.next;
删除中间结点
-
找到删除的位置position前一个节点cur
-
“插入的位置前一个节点”指向它下一个的下一个cur.next = cur.next.next
删除最后一个结点
-
找到删除的位置position前一个节点cur,前驱节点
-
判断前驱节点的后继是尾节点,然后将前驱节点的后继置空,执行cur.next = null;
/**
* 删除节点
*
* @param head 头节点
* @param position 删除节点位置
* @return 删除后的头节点
*/
public static Node deleteNode(Node head, int position) {
if (head == null) {
return null;
}
int size = length(head);
if (position > size || position < 1) {
System.out.println("越界");
return head;
}
if (position == 1) {
// curNode就是链表的新head
return head.next;
} else {
Node node = head;
int count = 1;
if (count < position - 1) {
node = node.next;
count++;
}
// node.next = node.next.next; 简化版
Node curNode = node.next;
node.next = curNode.next;
}
return head;
}