今天来练习以下单链表的一些操作,以下的操作都是带有头节点的链表。
定义链表节点类
定义了节点中的值,节点的下一个节点,和一些基本的方法。
public static class ListNode{int val;ListNode next;public ListNode() {}public ListNode(int val){this.val=val;}public ListNode(int val, ListNode next) {this.val = val;this.next = next;}@Overridepublic String toString() {return "Node{" +"val=" + val +", next=" + next +'}';}}
头插
头插的实现很简单,让想要插入的节点指向头节点指向的第一个节点,再让头节点指向想要插入的节点即可。
public static void headInsert(ListNode root,ListNode node){node.next = root.next;root.next = node;}
尾插
尾插也很简单,直接循环遍历到最后一个节点,让其指向要插入的节点即可。
public static void tailInsert(ListNode root,ListNode node){while(root.next!=null){root=root.next;}root.next=node;}
链表反转
链表的反转稍微复杂一点。
我们需要用到三个节点来保存链表中的节点。
定义cur指向当前想要反转的节点。
定义pre指向当前想要反转的节点的前一个结点,初始为null。
定义next指向当前想要反转的节点的下一个结点。
通过循环,先找到next,然后让cur指向pre,实现反转,再将pre和cur整体向后动以便完成下个结点的反转。
例如想要反转链表root->1->2->3,首先选中cur和next
当前pre为空然后让cur指向pre,再整体往后。
随后再走一遍流程
继续再走一遍完成,改变root指向。
public static void reverasl(ListNode root){ListNode prev = null;ListNode curr = root.next;while (curr != null) {ListNode next = curr.next;curr.next = prev;prev = curr;curr = next;}root.next = prev;}