1
1
package ssj .algorithm .collections ;
2
2
3
3
import com .google .common .base .Preconditions ;
4
+ import ssj .algorithm .Queue ;
4
5
import ssj .algorithm .SearchTree ;
5
6
import ssj .algorithm .Stack ;
6
7
@@ -107,7 +108,7 @@ private Node rebuildCore(T[] pre_order, int pre_start, int pre_end, T[] mid_orde
107
108
}
108
109
109
110
/**
110
- * 求一个树中两个节点的公共节点,这是第一中方法,下面还有第二中方法
111
+ * 求一个树中两个节点的公共节点,这是第一种方法。
111
112
*
112
113
* @param one
113
114
* @param other
@@ -124,29 +125,88 @@ public T commonParent(T one, T other) {
124
125
}
125
126
}
126
127
127
- private T getCommonParent (Node start_node , T one , T other ) {
128
+ /**
129
+ * 求一个树中两个节点的公共节点,这是第二种方法
130
+ *
131
+ * @param one
132
+ * @param other
133
+ * @return
134
+ */
135
+ public T getCommonParent (T one , T other ) {
128
136
Preconditions .checkNotNull (one );
129
137
Preconditions .checkNotNull (other );
130
- if (start_node == null ) {
131
- return null ;
138
+ Preconditions .checkArgument (!one .equals (other ));
139
+
140
+ if (isEmpty ()) return null ;
141
+
142
+ Node one_node = null ;
143
+ Node other_node = null ;
144
+ Queue <Node > preorder_queue = new LinkedList <>();
145
+ preorder_queue .appendTail (_head );
146
+ while (!preorder_queue .isEmpty () && (one_node == null || other_node == null )) {
147
+ Node cur_node = preorder_queue .removeHead ();
148
+ if (cur_node .getValue ().equals (one )) {
149
+ one_node = cur_node ;
150
+ } else if (cur_node .getValue ().equals (other )) {
151
+ other_node = cur_node ;
152
+ }
153
+
154
+ if (cur_node .getLeft () != null ) {
155
+ preorder_queue .appendTail (cur_node .getLeft ());
156
+ }
157
+
158
+ if (cur_node .getRight () != null ) {
159
+ preorder_queue .appendTail (cur_node .getRight ());
160
+ }
132
161
}
162
+ if (one_node == null || other_node == null ) return null ;
163
+ return getCommonNode (one_node , other_node ).getValue ();
164
+ }
133
165
134
- T left_parent ;
135
- if ((left_parent = getCommonParent (start_node .getLeft (), one , other )) != null ) {
136
- return null ;
166
+ private Node getCommonNode (Node one , Node other ) {
167
+ Preconditions .checkArgument (other != one );
168
+ int one_length = pathLength (one );
169
+ int other_length = pathLength (other );
170
+ while (one_length > other_length ) {
171
+ one = one .getParent ();
172
+ one_length --;
137
173
}
138
174
139
- T right_parent ;
140
- if (( right_parent = getCommonParent ( start_node . getRight (), one , other )) != null ) {
141
- return null ;
175
+ while ( one_length < other_length ) {
176
+ other = other . getParent ();
177
+ other_length -- ;
142
178
}
143
179
180
+ while (one != null && other != null ) {
181
+ if (one .equals (other )) {
182
+ return one ;
183
+ }
184
+ one = one .getParent ();
185
+ other = other .getParent ();
186
+ }
144
187
return null ;
145
188
}
146
189
190
+ /**
191
+ * 计算从这个节点到根节点的距离,也就是路径长
192
+ *
193
+ * @param node
194
+ * @return
195
+ */
196
+ private int pathLength (Node node ) {
197
+ Preconditions .checkNotNull (node );
198
+ int result = 0 ;
199
+ while (node != null ) {
200
+ result ++;
201
+ node = node .getParent ();
202
+ }
203
+ return result ;
204
+ }
205
+
147
206
private Node getCommonNode (Stack <Node > one , Stack <Node > other ) {
148
207
Preconditions .checkNotNull (one );
149
208
Preconditions .checkNotNull (other );
209
+ Preconditions .checkArgument (!one .equals (other ));
150
210
if (one .isEmpty () || other .isEmpty ()) {
151
211
return null ;
152
212
}
0 commit comments