Java单向链表的实现
一.前言
Java中实现List接口的方法不只有ArrayList,还可以通过LinkedList来实现。这个LinkedList是一个单向链表,它内部的每一个元素都指向下一个元素。本文并不是对Java内部的LinkedList进行讲解,而是另外去创建一个单向链表类,完成简单的增删查改。
二.单向链表的结构
链表是离散存储线性结构,n个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点。
图上的head为头节点,而头节点指向的节点为首节点,最后一个节点为尾节点。
三.实现单向链表
1.准备
定义一个类作为节点,一个节点包括两个元素,数据域和指针域,即存储的数据和其指向的的下一个节点。
public class Node { //数据域 public Integer data; //指针域,指向下一个节点 public Node next; public Node() { } public Node(int data) { this.data = data; } public Node(int data, Node next) { this.data = data; this.next = next; } }
在启动类中,定义变量为head节点。
private static Node head = new Node();
2.添加节点
在启动类中添加add方法。
以head节点开始,遍历去找它有无next节点,没有的话,该next节点即为新增的节点。
public static void addData(int value) { //初始化要加入的节点 Node newNode = new Node(value); //临时节点 Node temp = head; // 找到尾节点 while (temp.next != null) { temp = temp.next; } // 已经包括了头节点.next为null的情况了~ temp.next = newNode; }
3.遍历链表
在启动类中添加遍历方法。
它会从首节点开始,不断找它next有没节点。
public static void traverse(Node head) { //临时节点,从首节点开始 Node temp = head.next; while (temp != null) { if (temp.data != null) { System.out.println("编号:" + temp.data); } //继续下一个 temp = temp.next; } }
然后输出结果。
4.查询链表的长度
遍历节点有没next节点,直到next节点为null(即尾节点),记录这个遍历次数。
public static int linkListLength(Node head) { int length = 0; //临时节点,从首节点开始 Node temp = head.next; // 找到尾节点 while (temp != null) { length++; temp = temp.next; } return length; }
5.插入节点
在指定位置插入节点。找到该位置的上一个节点,将上一个节点的next指向新插入节点,而新插入节点的next则改为原本上一个节点的next指向。
public static void insertNode(Node head, int index, int value) { //首先需要判断指定位置是否合法, if (index < 1 || index > linkListLength(head) + 1) { System.out.println("插入位置不合法。"); return; } //临时节点,从头节点开始 Node temp = head; //记录遍历的当前位置 int currentPos = 0; //初始化要插入的节点 Node insertNode = new Node(value); while (temp.next != null) { //找到上一个节点的位置了 if ((index - 1) == currentPos) { //temp表示的是上一个节点 //将原本由上一个节点的指向交由插入的节点来指向 insertNode.next = temp.next; //将上一个节点的指针域指向要插入的节点 temp.next = insertNode; return; } currentPos++; temp = temp.next; } }
6.删除节点
找该删除节点的上一个节点,将上一个节点的next指向改为该删除节点的next。
public static void deleteNode(Node head, int index) { //首先需要判断指定位置是否合法, if (index < 1 || index > linkListLength(head) + 1) { System.out.println("删除位置不合法。"); return; } //临时节点,从头节点开始 Node temp = head; //记录遍历的当前位置 int currentPos = 0; while (temp.next != null) { //找到上一个节点的位置了 if ((index - 1) == currentPos) { //temp表示的是上一个节点 //temp.next表示的是想要删除的节点 //将想要删除的节点存储一下 Node deleteNode = temp.next; //想要删除节点的下一个节点交由上一个节点来控制 temp.next = deleteNode.next;return; } currentPos++; temp = temp.next; } }
四.总结
通过上面的例子,我们可以简单理解链表的原理。只需要知道头节点,就可以对链表进行任何操作。