1、原理
元素:真实存在于线性表中的内容,是我们关心的核心内容。
结点:为了组织链表而引入的结构,除了保存元素,还保存指向下一个结点的引用。其中尾结点的next==null.
链表:最终的线性表,表示逻辑上的[2 4 2]。
目前通过链表的头结点(head)来代表一整条链表,因为通过head可以找到所有的结点。
某条链表的头结点是null,表示头结点不存在,进一步可以表示是一条没有头结点的链表,也就是一条空链表。
当前结点(current/cur):表示链表中某个结点。
前驱结点(previous/pre):表示链表中某个结点的前一个结点,头结点没有前驱结点。
后继结点(next):表示链表中某个结点的后一个结点,尾结点没有后继节点。
结点定义:
package LinkedList;
public class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
this.next=null;
}
@Override
public String toString() {
return "Node{" +
"val=" + val +
", next=" + next +
'}';
}
}
链表的手工创建:
Node n3=new Node(3);
Node n4=new Node(4);
Node n2=new Node(2);
Node n1=new Node(1);
n3.next=n4;
n4.next=n2;
n2.next=n1;
n1.next=null;
Demo
package LinkedList;
public class NodeDemo {
// 头插之后会返回新的头结点,因为头节点在变化
private static Node pushHead(Node head, int val) {
Node node=new Node();
node.val = val;
if (head == null) {
node.next = null;
return node;
} else {
node.next = head;
return node;
}
}
private static void printLinkedListByHead(Node head) {
Node cur = head;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
}
public static void main(String[] args) {
Node head = null;
head = pushHead(head, 1);
head = pushHead(head, 2);
head = pushHead(head, 3);
printLinkedListByHead(head); // 3 2 1
}
public static void main3(String[] args) {
Node n1 = new Node();
Node n3 = new Node();
Node n2 = new Node();
Node n6 = new Node();
n1.val = 1;
n3.val = 3;
n2.val = 2;
n6.val = 6;
n1.next = n3;
n3.next = n2;
n2.next = n6;
n6.next = null;
Node prev = n3;
Node n100 = new Node();
n100.val = 100;
n100.next = prev.next;
prev.next = n100;
Node cur = n1;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
}
public static void main2(String[] args) {
Node n1 = new Node();
Node n3 = new Node();
Node n2 = new Node();
Node n6 = new Node();
n1.val = 1;
n3.val = 3;
n2.val = 2;
n6.val = 6;
n1.next = n3;
n3.next = n2;
n2.next = n6;
n6.next = null;
Node prev = n3;
prev.next = prev.next.next;
Node cur = n1;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
}
public static void main1(String[] args) {
Node n1 = new Node();
Node n3 = new Node();
Node n2 = new Node();
Node n6 = new Node();
n1.val = 1;
n3.val = 3;
n2.val = 2;
n6.val = 6;
n1.next = n3;
n3.next = n2;
n2.next = n6;
n6.next = null;
// 因为 n1 是第一个结点,所以我们称为头结点
Node head = n1; // 让 head 和 n1 指向同一个结点对象
// head 作为头结点,代表一整条链表
// 如何 head 链表的遍历
// 只需要打印每个元素即可
Node cur = head;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
int count = 0;
cur = head;
while (cur != null) {
count++;
cur = cur.next;
}
System.out.println("链表长度是: " + count);
// 暂时不考虑链表是 empty 的情况(链表中至少有一个结点)
Node last = head;
while (last.next != null) {
last = last.next;
}
System.out.println(last.val);
// 假定 head 中至少有两个结点
Node secondLast = head;
while (secondLast.next.next != null) {
secondLast = secondLast.next;
}
System.out.println(secondLast.val);
// 找第 n 个结点
// 需要向后走 n - 1 步
int n = 4;
Node nCur = head;
for (int i = 1; i < n; i++) {
// 向后走一步
nCur = nCur.next;
}
System.out.println(nCur.val);
boolean isFound = false;
int target = 4;
cur = head;
while (cur != null) {
if (cur.val == target) {
isFound = true;
}
cur = cur.next;
}
System.out.println(isFound);
}
}
执行结果: