-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNode.java
More file actions
156 lines (133 loc) · 4.14 KB
/
Node.java
File metadata and controls
156 lines (133 loc) · 4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* A "node" represents a single element in a sequence. Think of it like a link
* in a chain -- the node contains an element of data and a reference to the
* next element in the sequence.
*
* This node is "doubly linked" -- it has references to the next node in the
* chain and the previous node in the chain. The join and split methods manage
* both connections simultaneously to ensure that the consistency of links in
* the chain is preserved at all times.
*
* @param <T> the element type stored in the node
*
* @author Tony Allevato
* @version 2012.10.22
*/
public class Node<T>
{
//~ Fields ................................................................
// The data element stored in the node.
private T data;
// The next node in the sequence.
private Node<T> next;
// The previous node in the sequence.
private Node<T> previous;
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Creates a new Node with the specified data.
*
* @param data the data for the node
*/
public Node(T data)
{
this.data = data;
}
//~ Public methods ........................................................
// ----------------------------------------------------------
/**
* Gets the data in the node.
*
* @return the data in the node
*/
public T data()
{
return data;
}
// ----------------------------------------------------------
/**
* Sets the data in the node.
*
* @param newData the new data to put in the node
*/
public void setData(T newData)
{
data = newData;
}
// ----------------------------------------------------------
/**
* Gets the node that follows this one in the sequence.
*
* @return the node that follows this one in the sequence
*/
public Node<T> next()
{
return next;
}
// ----------------------------------------------------------
/**
* Gets the node that precedes this one in the sequence.
*
* @return the node that precedes this one in the sequence
*/
public Node<T> previous()
{
return previous;
}
// ----------------------------------------------------------
/**
* Joins this node to the specified node so that the one passed as a
* parameter follows this node. In other words, writing {@code A.join(B)}
* would create the linkage A <-> B.
*
* An exception will be thrown if this node already has another node
* following it, or if {@code newNext} already has another node preceding
* it. In this case, you must {@link #split()} the nodes before you can
* join it to something else.
*
* @param newNext the node that should follow this one
* @return this node, so that you can chain methods like
* {@code A.join(B.join(C))}
*
* @throws IllegalStateException if there is already a node following this
* node or if there is already a node preceding {@code newNext}
*/
public Node<T> join(Node<T> newNext)
{
if (this.next != null)
{
throw new IllegalStateException("A node is already following "
+ "this one.");
}
else if (newNext != null && newNext.previous != null)
{
throw new IllegalStateException("A node is already preceding "
+ "the one passed to this method.");
}
else
{
this.next = newNext;
if (newNext != null)
{
newNext.previous = this;
}
return this;
}
}
// ----------------------------------------------------------
/**
* Splits this node from its follower and then returns the follower.
*
* @return the node that used to follow this node before they were split
*/
public Node<T> split()
{
Node<T> oldNext = this.next;
if (next != null)
{
next.previous = null;
}
this.next = null;
return oldNext;
}
}