单链表的具体实现

前言

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接顺序实现的。

链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表的插入的事件复杂度是O(N),查找的事件复杂度是O(1);

主要实现
public class SingleLinkedList<T> {

    //头结点
    private Node<T> header;

    public SingleLinkedList() {
    }

    public void insert(T[] arr) {
        for (T t : arr) {
            insertLast(t);
        }
    }

    public void insertLast(T item) {
        if (isEmpty()) {
            header = new Node<T>(item);
            return;
        }
        Node<T> node = header;
        while (node.next != null) {
            node = node.next;
        }
        Node<T> newNode = new Node<>(item);
        node.setNext(newNode);
    }


    public void insertFirst(T item) {
        if (isEmpty()) {
            header = new Node<>(item);
            return;
        }

        Node<T> newNode = new Node<>(item);
        Node<T> tem = header;
        header = newNode;
        header.setNext(tem);
    }

    public Node<T> remove(T item) {
        if (isEmpty()) {
            return null;
        }
        Node<T> node = header;
        if (node.item == item) {
            return deleteHeaderNode();
        } else {
            //找到要删除节点的上一个节点;
            while (node.next != null) {
                if (item.equals(node.next.item)) {
                    break;
                }
                node = node.next;
            }
            Node<T> delNode = node.next;
            if (delNode != null) {
                node.setNext(delNode.next);
                return delNode;
            }
        }
        return null;
    }

    //删除头结点
    private Node<T> deleteHeaderNode() {
        Node<T> deleteNode = header;
        if (deleteNode.next == null) {
            header = null;
        } else {
            header = deleteNode.next;
        }
        return deleteNode;
    }


    public boolean isEmpty() {
        return header == null;
    }

    /**
     * 反转单链表
     * 反转 1-2-3-4-5-6
     * 6-5-4-3-2-1
     */
    public void reversal() {
        Node node = header;
        reversal(node);
    }

    /**
     * 遍历法
     * 反转链表:将当前节点(curNode)和上一个节点(preNode)记录下来,让curNode的next指向preNode;
     * 重新为header节点赋值;
     *
     * @param node
     */
    public void reversal(Node<T> node) {
        Node<T> preNode = null;
        Node<T> curNode = node;
        while (curNode != null) {
            Node<T> next = curNode.next;
            curNode.setNext(preNode);
            //保存上一个节点和当前节点
            preNode = curNode;
            curNode = next;
        }
        //重新赋值header节点
        header = preNode;
    }


    public void traversal() {
        if (isEmpty()) {
            return;
        }
        Node<T> node = header;
        StringBuilder stringBuilder = new StringBuilder();
        while (node != null) {
            stringBuilder.append(node.item).append("  ");
            node = node.next;
        }

        Logger.e(stringBuilder.toString());
    }

    static class Node<T> {

        private T item;
        private Node<T> next;

        public Node(T item) {
            this.item = item;
        }

        public T getItem() {
            return item;
        }

        public void setItem(T item) {
            this.item = item;
        }

        public Node<T> getNext() {
            return next;
        }

        public void setNext(Node<T> next) {
            this.next = next;
        }

    }
}

以上就是单链表的主要操作,如有问题,请多指教,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值