数据结构与算法之双向链表 <二>
来源:互联网 发布:苹果6s只能用2g网络 编辑:程序博客网 时间:2024/06/05 02:41
双向链表优缺点
优点
对于链表中一个给定的节点,可以从两个方向进行操作。在单向链表中只有获得节点的前驱节点才能删除这个节点。然而在双向链表中即使没有这个节点的前驱节点也能删除这个节点。缺点
1.每个节点需要添加一个额外的指针,因此需要更多的空间开销。
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
- 数据结构与算法之双向链表 <二>
- 算法与数据结构之双向链表
- 数据结构与算法python版(二)--双向链表
- 数据结构与算法专题之线性表——链表(二)双向链表
- 算法与数据结构之四----双向链表
- 数据结构与算法-----双向线性链表
- [数据结构与算法]双向链表
- 数据结构与算法:双向链表
- 数据结构与算法(双向链表)
- java数据结构与算法-双向链表
- 《数据结构和算法》之双向链表
- 算法学习之数据结构之双向链表
- 数据结构与算法之六 双向链表和循环链表
- 数据结构与算法分析-双向链表的实现
- Linux c 算法与数据结构--双向链表
- 数据结构与算法Javascript描述(四)双向链表
- 数据结构与算法学习04:双向链表
- Linux c 算法与数据结构--双向链表
- 原型模式
- nodejs内置模块
- python爬虫—hello world!
- JavaScript基础知识(8)
- 如何调试fft与ntt
- 数据结构与算法之双向链表 <二>
- 《ACM程序设计》书中题目 T
- 外观模式
- JavaScript基础知识(9)
- 剑指offer 二进制中1的个数
- 使用并设置urxvt终端
- Sicily Single-link Clustering
- 状态dp hdu1074
- unity状态模式