链表的相关概念
单链表就像锁链一样,将元素相互连接起来。每个节点都有一个小尾巴(next指针),用来指向下一个元素的节点地址。
链表节点主要分为头节点,普通节点和尾节点。头节点没有前驱节点,尾节点没有后继节点,普通节点只有一个后继节点,但是可以有多个前驱节点,如下图所示
虚拟节点
虚拟节点经常会在题目和工程上出现,方便我们处理头节点,虚拟一般称为dummyNode,该节点的next指针指向头节点(head),即dummyNode.next=head。若使用虚拟节点,head节点应该使用dummyNode.next获取
创建链表
public class LinkNode {
public int data;//节点数据
public LinkNode next;//后继节点地址
public LinkNode(int data) {
this.data = data;
this.next = null;
}
}
可是在JVM中是怎么创建链表的呢?
//1.声明引用变量
LinkNode linkNode1;
//2.创建对象并使得linkNode引用变量指向本对象
linkNode1 = new LinkNode(1);
//3.构建连接
LinkNode linkNode2 = new LinkNode(3);
LinkNode linkNode3 = new LinkNode(9);
linkNode1.next = linkNode2;
linkNode2.next = linkNode3;
在java中,我们使用new来创建对象,而这新创建的对象(new LinkNode(1))被存放在JVM中的堆中,我们声明的引用变量(LinkNode linkNode1)被存放在栈中,通过栈中的引用,我们就可以构建链表的结构
链表的增删改查
1.遍历链表
public int getLinkNodeLength(LinkNode head){
int length = 0;
LinkNode node = head;
while (node!=null){
length++;
node=node.next;
}
return length;
}
2.链表插入
/**
* @param head 链表头节点
* @param newNode 待插入节点
* @param position 插入位置,从1开始
* @return 插入后链表的头节点
*/
public LinkNode insertLinkNode(LinkNode head, LinkNode newNode, int position) {
if (head == null) {//链表为空,待插入节点作为头节点
return newNode;
}
int length = getLinkNodeLength(head);
if (position > length + 1 || position < 1){//位置参数越界
return head;
}
if(position==1){//表头插入
newNode.next=head;
return newNode;
}
LinkNode node = head;
length = 1;
while (length!=position-1){
node=node.next;
length++;
}
newNode.next=node.next;
node.next=newNode;
return head;
}
3.链表删除
/**
* @param head 链表头节点
* @param position 删除位置.从1开始
* @return 删除后链表头节点
*/
public LinkNode deleteLinkNode(LinkNode head, int position) {
if (head == null) return null;
int length = getLinkNodeLength(head);
if (position > length || position < 1) return head;
if (position == 1) return head.next;
LinkNode node = head;
length = 1;
while (length != position - 1) {
node = node.next;
length++;
}
node.next=node.next.next;
return head;
}