首先需要定义一个链表节点类:
public class Node{
public int val; //元素;
public Node next; //指向下一个节点对象,next=null表示链表的最后一个节点;
}
public Node(int val){
this.val=val;
this.next=null;
}
链表为空或者不为空时:head==null; head!=null; 插入节点;
第一种简单分析;
public static Node pushFront(Node head, int val) {
Node node = new Node(val); // 1. 把元素 val 装入结点中
if(head==null){
return node;
}else{
node.next=head;
return node;
}
}
第二种可以简化第一种方法
public static Node pushFront(Node head, int val) {
// 1. 把元素 val 装入结点中
Node node = new Node(val);
node.next = head;
return node;
}
已经把元素放入节点中了,直接可以令node.next = head;为原来的头节点,直接返回node就可以实现头插;
头删:在head不为空的情况下直接令head=head.next就可以啦
public static Node popFront(Node head) {
// head != null
//省略了head=head.next,直接返回head.next也是可以的;
return head.next;
}
遍历链表+打印链表:
把头节点赋给cur只要cur不为空就一直执行,cur=cur.next,往下走,打印每一个cur中的元素;
private static void printLinkedList(Node head) {
Node cur = head;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
}
尾插:给出一个链表只要找到最后一个元素的next就可以实现尾插,可以用遍历的方法;
定义出一个Node类型的last,当last.next为空时证明已经找到了这个元素;
还需要考虑当前链表是否为空链表;两种情况;
private static Node pushBack(Node head, int val) {
Node node = new Node(val);//把元素装入链表中;
if (head != null) {
//判断链表是否为空;
Node last = head; // 定义一个last为头结点,一直往下判断;
while (last.next != null) {
last = last.next;
}
last.next = node;//第一句话已经把元素放入节点中了,所以用last.next=node 就把链表链接了;
return head;
} else {
return node; //链表中一个元素都没有直接返回node就可以了;
}
}
尾删:考虑两种情况链表为空和链表不为空;只要找到6元素之前的next就可以实现尾删了;
当链表为空的时候,链表中没有节点,直接返回null就可以了;
当链表不为空的时候,令last为头结点,只要last.next.next=null;就证明已经找到最后一个元素之前的元素了;令last=last.next,一直往下找;last.next=null,此时last已经为最后一个节点;return head;返回头节点就可以了
private static Node popBack(Node head) {
// head != null考虑是否为空链表;
if (head.next == null) {
return null;
} else {
Node last = head;
while (last.next.next != null) {
last = last.next;
}
// last 是最后一个结点
last.next = null;
return head;
}
}
反转链表:
下面图中为初始链表和反转链表之后的结果,首先链表不为空,而且反转链表需要三个变量
令
ListNode prev = null; ListNode cur = head; ListNode next = cur.next;
令前驱为空,cur为链表头结点,next为cur.next;
当cur不为空时用next来保存cur.next,让cur.next指向前驱,这时cur的指向已经变了,指向了前面的节点,接着让
prev = cur;cur = next;往下进行保存新的prev和cur;
public class ListNode {
public int val;
public ListNode next;
public ListNode(int val) { this.val = val; }
public ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}
}
删除某个节点:删掉某节点最重要的是该节点的前驱节点,如果链表为空则返回null;首先需要遍历整个链表的节点元素值;令cur=head头结点;判断 cur.next.val != val 不等于继续进行cur=cur.next; 如果等于则删掉该节点;cur.next = cur.next.next;(跳过了要删掉的节点),但是没有判断头结点,所以需要在判断头结点
public class ListNode {
public int val;
public ListNode next;
public ListNode(int val) { this.val = val; }
public ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return null;
}
ListNode cur = head;
while (cur.next != null) {
if (cur.next.val != val) {
cur = cur.next;
} else {
cur.next = cur.next.next;//跳过了要删掉的节点;
}
}
if (head.val == val) {
return head.next;
} else {
return head;
}
}
}