java数据结构——双向链表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yoonerloop/article/details/81516166

链表是非常常见的一类线性结构的数据结构,每个节点包含有指针域和数据域,常见的包括单项列表、双向列表、循环列表。这篇文章将详细介绍双向链表。

双端链表不同于单向链表仅有一个指针域指向下一个节点,而是同时持有下一个和上一个指针域,分别指向下一个和上一个节点,如下:

本文将介绍双向链表的插入节点、根据位置插入节点、删除头结点、删除尾节点、删除指定位置节点,查看链表元素、查看头结点、查看尾节点、查看链表长度、判断链表是否为空。

链表的节点表示:

class Node {

    //数据域
    public String data;
    //上一个节点
    public Node prev;
    //下一个节点
    public Node next;

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

在创建好链表节点之后下来看链表的构造方法和成员变量,成员方法包括一个完整链表的头结点、尾节点以及链表的长度:

class DoubleLinkedList {

    private Node tailNode;
    private Node headNode;
    private int length;

    public DoubleLinkedList() {
        tailNode = null;
        headNode = null;
    }
}

1、插入元素:尾部插入

    /**
     * 插入元素
     */
    public void insert(String value) {
        if (value == null || value.isEmpty()) {
            throw new NullPointerException();
        }
        Node node = new Node(value);
        if (headNode == null) {
            headNode = node;
            tailNode = headNode;
            tailNode.prev = null;
            tailNode.next = null;
        } else {
            tailNode.next = node;
            node.prev = tailNode;
            tailNode = node;
        }
        length++;
    }

2、插入元素:指定位置

    /**
     * 根据位置插入节点
     */
    public void insert(int position, String value) {
        //创建要插入的节点
        Node node = new Node(value);
        if (position >= length) {
            //直接插入到尾部
            insert(value);
            return;
        }
        if (position == 0) {
            Node firstNode = headNode;
            headNode = node;
            headNode.prev = null;
            headNode.next = firstNode;
            firstNode.prev = node;
        } else {
            //获取到该位置的节点
            Node nodeByPosition = getNodeByPosition(position);
            //上一个节点
            Node prevNode = nodeByPosition.prev;
            //下一个节点
            Node nextNode = nodeByPosition.next;
            //上一个节点next指向他
            prevNode.next = node;
            //他的上一个节点指向prev
            node.prev = prevNode;
            //他的下一个节点指向next
            node.next = nodeByPosition;
            //下一个节点的pre指向他
            nodeByPosition.prev = node;
        }
        length++;
    }

3、删除元素:删除头部

    /**
     * 删除链表头部
     */
    public Node deleteHead() {
        //获取根节点的下一个节点
        Node nextNode = null;
        Node firstNode = null;
        if (headNode != null) {
            nextNode = headNode.next;
        } else {
            return null;
        }
        if (nextNode == null) {
            headNode = null;
        } else {
            firstNode = headNode;
            nextNode.prev = null;
            headNode.next = null;
            headNode = nextNode;
        }
        length--;
        return firstNode;
    }

4、删除元素:删除尾部

    /**
     * 删除链表尾部
     */
    public Node deleteTail() {
        //获取根节点的下一个节点
        Node preNode = null;
        Node lastNode = null;
        if (tailNode != null) {
            preNode = tailNode.prev;
        } else {
            return null;
        }
        if (preNode == null) {
            headNode = tailNode;
        } else {
            lastNode = tailNode;
            tailNode.prev = null;
            preNode.next = null;
            tailNode = preNode;
        }
        length--;
        return lastNode;
    }

5、删除元素:删除指定位置

    /**
     * 删除指定位置节点
     */
    public Node deleteByPosition(int position) {
        if (position >= length) {
            throw new IllegalArgumentException(" position must be less than linklist all length ");
        } else {
            Node nodeByPosition = getNodeByPosition(position);
            if (position == 0) {
                //删除头结点
                Node deleteHead = deleteHead();
                return deleteHead;
            } else if (position == length - 1) {
                //删除尾节点
                Node deleteTail = deleteTail();
                return deleteTail;
            } else {
                //有头有尾
                //获取该节点的前一个和后一个节点
                Node prevNode = nodeByPosition.prev;
                Node nextNode = nodeByPosition.next;
                prevNode.next = nextNode;
                nextNode.prev = prevNode;
                length--;
                return nodeByPosition;
            }
        }
    }

6、根据位置获取节点

    /**
     * 根据位置获取节点
     */
    public Node getNodeByPosition(int position) {
        Node current = headNode;
        if (position >= length) {
            throw new IllegalArgumentException(" position must be less than linklist all length ");
        } else {
            for (int i = 0; i < length; i++) {
                if (i == position) {
                    break;
                }
                if (current != null) {
                    current = current.next;
                }
            }
        }
        return current;
    }

7、查看所有节点

    /**
     * 打印所有节点
     */
    public void displayAll() {
        Node current = headNode;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
    }

8、查看头结点

    /**
     * 查看头结点
     */
    public Node getheadNode() {
        return headNode;
    }

9、查看尾节点

    /**
     * 查看当尾节点
     */
    public Node getTailNode() {
        return tailNode;
    }

10、获取链表长度

    /**
     * 链表长度
     */
    public int length() {
        return length;
    }

11、判断链表是否为空

    /**
     * 判断链表是否为空
     */
    public boolean isEmpty() {
        return length == 0;
    }

猜你喜欢

转载自blog.csdn.net/yoonerloop/article/details/81516166