数据结构与算法之双向链表 <二>

来源:互联网 发布:苹果6s只能用2g网络 编辑:程序博客网 时间:2024/06/05 02:41
  1. 双向链表优缺点

    • 优点
      对于链表中一个给定的节点,可以从两个方向进行操作。在单向链表中只有获得节点的前驱节点才能删除这个节点。然而在双向链表中即使没有这个节点的前驱节点也能删除这个节点。

    • 缺点
      1.每个节点需要添加一个额外的指针,因此需要更多的空间开销。
      2.节点的插入或删除更加费时。

  2. 双向链表的建立
public class Node<E> {    // 储存的数据    private E data;    // 下一个节点    private Node<E> next;    // 上一个节点    private Node<E> front;    public E getData() {        return data;    }    public void setData(E data) {        this.data = data;    }    public Node<E> getNext() {        return next;    }    public void setNext(Node<E> next) {        this.next = next;    }    public Node<E> getFront() {        return front;    }    public void setFront(Node<E> front) {        this.front = front;    }

3.双向链表的插入操作

// 在链表最后增加链表节点    public void add(E obj) {        Node<E> node = new Node<>();        node.setData(obj);        // 如果链表为空 则首尾节点都指向第一个节点        if (headNode == null) {            headNode = node;            endNode = node;        } else {            // 不为空 将尾节点指向新增节点            endNode.setNext(node);            // 新节点指向尾节点            node.setFront(endNode);            // 尾节点后移            endNode = node;        }    }    // 在指定中间位置增加节点    public void add(int index, E element) {        // 创建新节点        Node<E> node = new Node<>();        node.setData(element);        // 判断是否为空链表        if (headNode == null) {            throw new NullPointerException("空链表");        }        // 判断位置是否超出界限        else if ((index < 0) || (index > this.size())) {            throw new ArrayIndexOutOfBoundsException("超出范围");        } else {            // 首节点插入            if (index == 0) {                node.setNext(headNode);                headNode.setFront(node);                headNode = node;            }            // 尾节点插入(相当于在链表最后增加链表节点)            else if (index == this.size()) {                endNode.setNext(node);                node.setFront(endNode);                endNode = node;            }            // 中间插入            else {                // 保护                Node<E> hnode = headNode;                // 将首节点移动到插入节点的前一个节点                for (int i = 1; i < index; i++) {                    hnode = hnode.getNext();                }                hnode.getNext().setFront(node);                node.setNext(hnode.getNext());                hnode.setNext(node);                node.setFront(hnode);            }        }    }

4.双向链表的删除

// 移除此列表中指定位置上的元素    public void remove(int index) {        if (headNode == null) {            throw new NullPointerException("空链表");        } else if ((index < 0) || (index >= this.size())) {            throw new ArrayIndexOutOfBoundsException("超出范围");        } else {            // 保护头结点            Node<E> hnode = headNode;            // 删除首节点            if (index == 0) {                headNode.getNext().setFront(null);                headNode = headNode.getNext();                // System.out.println(index + "号:" + hnode.getData().toString()                // + "移除成功");            }            // 删除尾节点            else if (index == (this.size() - 1)) {                endNode.getFront().setNext(null);                endNode = endNode.getFront();            }            // 删除中间节点            else {                // 移动到目标节点                for (int i = 0; i < index; i++) {                    hnode = hnode.getNext();                }                hnode.getFront().setNext(hnode.getNext());                hnode.getNext().setFront(hnode.getFront());            }        }    }

5.其他操作

// 返回此列表中指定位置上的元素。    public E get(int index) {        if (headNode == null) {            throw new NullPointerException("空链表");        } else {            // 遍历不到尾节点            for (Node<E> node = headNode; node.getNext() != null; node = node.getNext()) {                if (index == 0) {                    return node.getData();                }                index--;            }            // 尾节点单独检测 为什么是0因为index多运行了一次            if (index == 0) {                return endNode.getData();            } else                throw new ArrayIndexOutOfBoundsException("超出范围");        }    }    // 返回此列表的元素数。    public int size() {        if (headNode == null) {            return 0;        } else {            Node<E> node = headNode;            int count = 0;            while (node.getNext() != null) {                node = node.getNext();                count++;            }            return count + 1;        }    }    // 用指定的元素替代此列表中指定位置上的元素。    public E set(int index, E element) {        // 删除指定位置的元素        this.remove(index);        // 插入指定位置元素        this.add(index, element);        return element;    }

双向链表的基本操作就此完成

0 0
原创粉丝点击