2Java学习笔记之数据结构——双向链表

时间:2022-06-17
本文章向大家介绍2Java学习笔记之数据结构——双向链表,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在上一篇的单链表里,数据结构是单向的,只能从前往后一个一个找,而不能倒着来。因为每个节点Node只保存了下一个节点的位置。

这一篇的双向链表则是每个节点保存了上一个节点和下一个节点的位置,这样就能根据任何一个节点来寻找上或者下的节点了,向前向后都能遍历了。

直接上代码吧,比较简单。

package doublelink;

/**
 * Created by admin on 17/3/27.
 * 双链表的node
 */
public class Node {
    private String data;
    private Node next;
    private Node pre;

    public Node(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

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

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }
}
package doublelink;

/**
 * Created by admin on 17/3/27.
 * 双链表
 */
public class DoubleLinkedList {
    private int size;
    private Node head;

    public DoubleLinkedList() {
        size = 0;
    }

    public int size() {
        return size;
    }

    public void print() {
        if (size == 0) {
            System.out.println("空列表");
            return;
        }
        Node node = head;
        while (node != null) {
            System.out.println(node.getData());
            node = node.getNext();
        }
    }

    /**
     * 在末尾追加一个node
     * @param node
     */
    public void add(Node node) {
        if (node == null) {
            return;
        }
        if (head == null) {
            head = node;
        } else {
            Node last = head;
            //取到末尾的node
            while (last.getNext() != null) {
                last = last.getNext();
            }
            last.setNext(node);
            node.setPre(last);
        }

        size++;
    }

    public void insert(int index, Node node) {
        if (index < 0 || index > size) {
            throw new RuntimeException("越界");
        }
        if (node == null) {
            return;
        }
        //插头部
        if (index == 0) {
            if (head == null) {
                head = node;
            } else {
                node.setNext(head);
                head.setPre(node);
            }
        } else {
            //将被插入的位置的父节点
            Node beInsertedNode = head;
            for (int i = 0; i < index - 1; i++) {
                beInsertedNode = beInsertedNode.getNext();
            }
            //插到尾部的话,就不走括号内了
            if(beInsertedNode.getNext() != null) {
                node.setNext(beInsertedNode.getNext());
                beInsertedNode.getNext().setPre(node);
            }

            beInsertedNode.setNext(node);
            node.setPre(beInsertedNode);
        }

        size++;
    }

    /**
     * 根据index查找某个节点
     * @param index
     * @return
     */
    public Node get(int index) {
        if(index < 0 || index >= size) {
            throw new RuntimeException("越界");
        }
        Node node = head;
        for (int i = 0; i < index; i++) {
            node = node.getNext();
        }

        return node;
    }
}

代码也比较好理解,无非就是insert时注意一下设置前后节点的引用。

具体双向链表的用途,还是得看实际情况。