跳至主要內容

单链表


单链表

介绍

单链表(Singly Linked List)是一种常见的数据结构,用于存储和组织数据。它由一系列节点组成,每个节点包含两个部分:数据部分和指向下一个节点的引用(指针)。

单链表的特点是每个节点只有一个指针,即指向下一个节点,而最后一个节点指向空(null),表示链表的结束。

下面是一个单链表的示例:

头节点 -> 节点1 -> 节点2 -> 节点3 -> ... -> 尾节点 -> null

头节点是链表的起始点,尾节点是链表的结束点。每个节点包含一个数据域,用于存储具体的数据,以及一个指针域,指向下一个节点。

通过头节点,可以遍历整个链表。要访问链表中的特定节点,需要从头节点开始,依次沿着每个节点的指针找到目标节点。

单链表的插入和删除操作相对简单高效。插入一个新节点时,只需修改相邻节点的指针即可,而不需要移动其他节点。删除节点时,只需修改前一个节点的指针,将其指向待删除节点的下一个节点,然后释放待删除节点的内存空间。

然而,由于单链表的节点只包含一个指针,因此无法直接访问前一个节点,因此在删除和插入节点时需要特别注意。

单链表在某些情况下具有一些优势,例如插入和删除操作频繁,且对随机访问的需求较少的情况。但是,由于无法直接访问前一个节点,获取某个节点的前驱节点的操作比较麻烦,并且无法实现常数时间的随机访问。

另外,还有其他类型的链表,如双向链表(Doubly Linked List),它在每个节点中包含两个指针,分别指向前一个节点和后一个节点,从而提供了更多的灵活性和功能。

代码实现

public class SinglyLinkedList<T> {
    //用于存储数据
    public class Node {
        public T data;
        public Node nextNode;

    }

    public Node headNode;
    public int size;

    public SinglyLinkedList() {
        headNode = null;
        size = 0;
    }

    public boolean isEmpty() {
        if (headNode == null) return true;
        return false;
    }

    //在链表的头结点插入数据
    public void insertAtHead(T data) {
        Node newNode = new Node();
        newNode.data = data;
        newNode.nextNode = headNode;
        headNode = newNode;
        size++;
    }

    //在链表的尾结点插入数据
    public void insertAtEnd(T data) {
        if (isEmpty()) {
            insertAtHead(data);
            return;
        }
        Node newNode = new Node();
        newNode.data = data;
        newNode.nextNode = null;

        Node last = headNode;
        while (last.nextNode != null) {
            last = last.nextNode;
        }
        last.nextNode = newNode;
        size++;
    }

    //在给定节点后插入数据
    public void insertAfter(T data, T previous) {
        Node newNode = new Node();
        newNode.data = data;
        Node currentNode = this.headNode;
        while (currentNode != null && currentNode.data != previous) {
            currentNode = currentNode.nextNode;
        }
        if (currentNode != null) {
            newNode.nextNode = currentNode.nextNode;
            currentNode.nextNode = newNode;
            size++;
        }
    }

    //打印链表
    public void printList() {
        if (isEmpty()) {
            System.out.println("List is Empty!");
            return;
        }
        Node temp = headNode;
        System.out.print("List : ");
        while (temp.nextNode != null) {
            System.out.print(temp.data.toString() + " -> ");
            temp = temp.nextNode;
        }
        System.out.println(temp.data.toString() + " -> null");
    }

    //在链表中查找给定值
    public boolean searchNode(T data) {
        Node currentNode = this.headNode;
        while (currentNode != null) {
            if (currentNode.data.equals(data))
                return true;
            currentNode = currentNode.nextNode;
        }
        return false;
    }

    //删除头结点数据
    public void deleteAtHead() {
        if (isEmpty())
            return;
        headNode = headNode.nextNode;
        size--;
    }

    //从linked list中删除指定的值
    public void deleteByValue(T data) {
        if (isEmpty())
            return;

        //从头结点开始
        Node currentNode = this.headNode;
        Node prevNode = null; 

        if(currentNode.data.equals(data)) {
            //删除头部节点
            deleteAtHead();
            return;
        }
        //遍历链表来删除指定的值
        while (currentNode != null) {
            //找了待删除数据
            if (data.equals(currentNode.data)){
                prevNode.nextNode = currentNode.nextNode;
                size--;
                return; 
            }
            prevNode = currentNode;
            currentNode = currentNode.nextNode;
        }
    }
}
上次编辑于:
贡献者: Neil