本文为编程导航知识星球的算法通关村的学习笔记。
①编写Node类,共有两个属性,一个是节点的数据,一个是本类型的的next。构造方法,将data传参进去,即完成node节点的实例。
static class Node {
public int val;
public Node next;
Node(int x) {
val = x;
next = null;
}
}
②我们的数据类型是int,因此声明一个int型的数组,遍历数组,依次将数组内的数据传入构造方法,如果顺序是第一个,则让Node类型的head对象赋值为第一个节点,如果不是第一个,则将当前的对象的next属性赋值为newNode。
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6};
Node head = initLinkedList(a);
System.out.println(head);
}
private static Node initLinkedList(int[] array) {
Node head = null, cur = null;
for (int i = 0; i < array.length; i++) {
Node newNode = new Node(array[i]);
newNode.next = null;
if (i == 0) {
head = newNode;
cur = newNode;
} else {
cur.next = newNode;
cur = newNode;
}
}
return head;
}
}
以下将头节点称为head,将待插入的节点称为nodeInsert,待插入的位置称为position
①首部添加的时候,需要判断待插入的head是否为空,如果head为空,那么新增的节点即为头节点,赋值给head。如果position为1,将nodeInsert.next赋值为原先的head,然后再将head赋值为nodeInsert。
②在中间和尾部都需要注意位置越界的问题,比如传入的position为0或者超过链表长度+1,即链表长度为5,如果要在尾部插入则position要传入6,而不能大于6。
③在中间插入的时候,遍历到position-1的位置,得到这个节点pNode,要先将待插入的nodeInsert.next属性赋值为pNode.next,先把待插入的nodeInsert的next连接上原先位置的节点,然后再将pNode连接到nodeInsert。因为如果先将nodeInsert.next连接到nodeInsert,那么原来的next指针将会丢失,因此这个顺序绝对不可以出错。
/**
* 链表插入
*
* @param head 链表头节点
* @param nodeInsert 待插入节点
* @param position 待插入位置,取值从2开始
* @return 插入后得到的链表头节点
*/
public static Node insertNode(Node head, Node nodeInsert, int position) {
// 需要判空,否则后面可能会有空指针异常
if (head == null) {
return nodeInsert;
}
// 获取链表长度
int size = getLength(head);
//越界判断
if (position > size + 1 || position < 1) {
System.out.println("位置参数越界");
return head;
}
//在链表开头插入
if (position == 1) {
nodeInsert.next = head;
head = nodeInsert;
return head;
}
Node pNode = head;
int count = 1;
while (count < position - 1) {
pNode = pNode.next;
count++;
}
nodeInsert.next = pNode.next;
pNode.next = nodeInsert;
return head;
}
以下将头节点称为head,待删除的位置称为position
①position为头结点,将head赋值为head.next就可以了。
②position为尾节点,则遍历到倒数第二个,即遍历到节点长度size-1的位置,然后让这个位置的节点的next赋值为空即可
③中间位置的删除,遍历到position的前一个节点,使用一个中间变量存储position的节点,再让position-1处的节点的next赋值为position的next节点。比如删除位置4,用一个中间变量将位置3节点的next储存下来,然后将位置3的next属性赋值为位置4的next属性,即将3的next连接到5。
/**
* 删除节点
*
* @param head 链表头节点
* @param position 删除节点位置,取值从1开始
* @return 删除后的链表头节点
*/
public static Node deleteNode(Node head, int position) {
if (head == null) {
return null;
}
int size = getLength(head);
//思考一下,这里为什么是size,而不是size+1
// 删除的位置最多只能等于size,大于size则超出链表长度,自然找不到节点了
if (position > size || position <1) {
System.out.println("输入的参数有误");
return head;
}
if (position == 1) {
//curNode就是链表的新head
return head.next;
} else {
Node cur = head;
int count = 1;
while (count < position - 1) {
cur = cur.next;
count++;
}
Node curNode = cur.next;
cur.next = curNode.next;
}
return head;
}
占位,再补充。