Java 实现双链表
我在这个论坛上浏览了有关双链表实现的内容,但我无法掌握下面的代码Java 实现双链表,java,data-structures,linked-list,doubly-linked-list,Java,Data Structures,Linked List,Doubly Linked List,我在这个论坛上浏览了有关双链表实现的内容,但我无法掌握下面的代码 // instance variables of the DoublyLinkedList private final Node<E> header; // header sentinel private final Node<E> trailer; // trailer sentinel private int size = 0; // number of
// instance variables of the DoublyLinkedList
private final Node<E> header; // header sentinel
private final Node<E> trailer; // trailer sentinel
private int size = 0; // number of elements in the list
private int modCount = 0; // number of modifications to the list (adds or removes)
/**
* Creates both elements which act as sentinels
*/
public DoublyLinkedList() {
header = new Node<>(null, null, null); // create header
trailer = new Node<>(null, header, null); // trailer is preceded by header
header.setNext(trailer); // header is followed by trailer
}
//双链接列表的实例变量
私有最终节点头;//头球哨兵
私有最终节点尾部;//拖车哨兵
私有整数大小=0;//列表中的元素数
私有int modCount=0;//对列表的修改次数(添加或删除)
/**
*创建两个充当哨兵的元素
*/
公共双链接列表(){
header=新节点(null,null,null);//创建头
拖车=新节点(null,header,null);//拖车前面有header
header.setNext(拖车);//头后面跟着拖车
}
我看过关于链表和双链表的视频,但我还没有见过这种实现。例如:trailer=newnode(null,header,null)
?给定一个列表(任何类型),您至少需要知道如何到达第一个元素,以及如何告知何时看到最后一个元素
有几种方法可以安排满足这些要求
对于链表,要知道列表从何处开始,可以对第一个节点进行简单的引用,也可以使用始终存在的完整“虚拟”节点
要知道列表的结束位置,您可能有一个空的“next”引用,或者您可能有一个始终存在的完整的“dummy”节点
虚拟节点方法通常会产生更清晰的代码,因为这样所有实际节点将始终具有“上一个”节点,而所有实际节点将始终具有“下一个”节点
这似乎是代码提取中采用的方法。您可能有一些双链接列表,如:
/**
* A double linked list.
*
*/
public class DoubleLinkedList<E> {
private final Node<E> header; // header sentinel
private final Node<E> trailer; // trailer sentinel
private int size = 0; // number of elements in the list
private int modCount = 0; // number of modifications to the list (adds or removes)
public DoubleLinkedList() {
this.header = new Node<>(
// The successor of the header is the trailer.
// It will be set with: header.setNext(trailer);
null,
// The predecessor of the header is always null,
// because there there is no node before the first
null,
// The payload of the node is null.
// I guess it is just a part of the example.
null
);
this.trailer = new Node<>(
// The successor of the trailer is always null,
// because there there is no node after the last
null,
// The predecessor of the trailer is the header
// at construction of this object
header,
// The payload of the node is null.
// I guess it is just a part of the example.
null
);
// Now is the successor of the header set to the trailer.
header.setNext(trailer);
}
// Some list methods like add, remove, get, ...
/**
* The nodes of the List
*
* @param <T> The type of the stored objects in the list.
*/
static class Node<T> {
/**
* The predecessor of this node.
*/
private Node<T> predecessor;
/**
* The successor of this node.
*/
private Node<T> successor;
/**
* The payload
*/
private final T payload;
public Node(final Node<T> successor, final Node<T> predecessor, final T payload) {
this.predecessor = successor;
this.successor = successor;
this.payload = payload;
}
// Getter and Setter:
private Node<T> getPredecessor() {
return this.predecessor;
}
private void setNext(final Node<T> next) {
this.predecessor = next;
}
private Node<T> getSuccessor() {
return this.successor;
}
private void setPrevious(final Node<T> previous) {
this.successor = previous;
}
private T getPayload() {
return this.payload;
}
}
}
/**
*双链接列表。
*
*/
公共类双链接列表{
私有最终节点头;//头哨兵
私有最终节点拖车;//拖车哨兵
private int size=0;//列表中的元素数
private int modCount=0;//对列表的修改次数(添加或删除)
公共双链接列表(){
this.header=新节点(
//标题的后续部分是尾部。
//它将设置为:header.setNext(拖车);
无效的
//标头的前置项始终为空,
//因为在第一个节点之前没有节点
无效的
//节点的有效负载为空。
//我想这只是例子的一部分。
无效的
);
this.traile=新节点(
//预告片的后续项始终为空,
//因为在最后一个节点之后没有节点
无效的
//拖车的前身是收割台
//在建造这个物体时
标题,
//节点的有效负载为空。
//我想这只是例子的一部分。
无效的
);
//现在是标题集到拖车的后续项。
标题。设置下一步(拖车);
}
//一些列表方法,如添加、删除、获取。。。
/**
*列表的节点
*
*@param列表中存储对象的类型。
*/
静态类节点{
/**
*此节点的前置节点。
*/
专用节点前置器;
/**
*此节点的后续节点。
*/
私有节点继承者;
/**
*有效载荷
*/
专用最终T载荷;
公共节点(最终节点后续节点、最终节点前置节点、最终T有效负载){
这个。前任=继任者;
这个后继者=后继者;
这个有效载荷=有效载荷;
}
//接受者和接受者:
私有节点getPreference(){
把这封信还给我;
}
私有void setNext(最终节点next){
this.preference=next;
}
私有节点getSuccessor(){
把这个交给继任者;
}
私有void setPrevious(最终节点previous){
这个后继者=先前的;
}
私有T getPayload(){
返回此有效载荷;
}
}
}
这在架构上不是很漂亮,但我认为这个解释符合您的情况。您看过节点构造函数吗?你们到底不确定什么?拖车只是指向第一个节点的指针。标头是当前的最后一个节点。如果添加下一个节点,则它将更改。。。是常见的解决方案。
java.util.LinkedList
已经包含对上一个和下一个的引用elements@tgdaviesheader=新节点(null,null,null);trailer=新节点(null,header,null);我的疑问主要在于此。节点构造函数的每个参数代表什么?