我已经被困这个问题了近一天了。基本上,我给了10000行二进制代码。为简单起见,我将展示前10行。
1 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0 0 1 1 1 1
0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 1 1 0 1 0 1 1 0 1
0 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 0 1 0 0 1 1 0 0 0
0 1 0 0 1 1 1 0 1 0 1 1 0 0 1 1 1 1 1 0 0 1 0 0
0 1 0 0 1 0 1 0 0 0 0 1 0 0 1 1 1 0 1 1 0 1 0 1
0 0 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0
1 1 1 0 0 1 1 0 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 1
每一行对应于从二进制树的根到离开的路径。每行都有一个假(你可以为第1行提供节点“A”,为第2行提供“B”...你想要命名节点的任何内容),每行包含24个二进制代码。例如,101
对应于以下图片,其中0
和1
分别对应左右。
(root)
\ 1
\
(sentinel node)
/
0 /
(sentinel code)
\ 1
\
(leave)
问题是:我一直未能编写treeInsert
方法的代码。 (我稍后会使用DFS来遍历树,但这不是现在主要关注的问题。)主要关注的是我无法对treeInsert进行编码,这意味着我无法为前10行构建适当的二叉树。
此外,这对我来说也是一个设计问题,因为我不确定我是否应该为前哨节点设置0
和1
的值,因为它似乎没有在这种情况下创建Edge对象的意义。
我有以下代码,我认为它不起作用或做我想要的:
class Node{
public enum Color{
WHITE, BLACK, GRAY
}
Integer node;
Node left, right, p;
Color color;
int N;
int prefix_code;
public Node(){
this.node = null;
this.prefix_code = -1;
N = 0;
}
public Node(int node, int prefix_code){
this.node = node;
this.prefix_code = prefix_code;
N = 1;
}
public String toString(){
if(node != null){
return node + "";
} else{
return "nil";
}
}
public int hashCode(){
return (int)(node * 31);
}
public boolean equals(Object o){
if(o == this){
return true;
}
if(o == null || getClass() != o.getClass() ){
return false;
}
Node other = (Node) o;
return node == other.node;
}
public Node[] adj(){
Node[] adjacent_v = new Node[]{left, right};
return adjacent_v;
}
public boolean isNull(){
return node == null;
}
}
class BinaryTree{
Node root;
Node nil;
public BinaryTree(){
root = new Node(-1,-1); // make sure Tree is not empty
nil = new Node();
}
public int size(){
return size(root);
}
public int size(Node x){
if(x == null){
return 0;
} else{
return x.N;
}
}
/*
* Insertion begins at the root of the tree
* and the pointer x traces a simple path downward
* looking for a nil to replace with the input item z.
*
* The method also maintains a trailing pointer y as
* the parent of x.
*
* Within the while loop,these two pointers will
* move down the tree, going left or right depending on
* the comparison of z.key with x.key, until x becomes nil.
*
* This nil occupies the position where we wish to place the
* input item z.
*
* The trailing pointer is needed because by the time we find
* the NIL where z belongs, the search has proceeded one step
* beyond the node that needs to be changed.
*
*/
public void treeInsert(Integer[] bits, int node){
Node y = nil;
Node x = root;
for(int i = 0; i < bits.length; i++){
Node z;
if(i == 23){
z = new Node(node, bits[i]);
} else{
z = new Node(-1, bits[i]);
}
y = x;
if(bits[i] == 0){
x = x.left;
} else{
x = x.right;
}
z.p = y;
if(y.equals(nil)){
root = z;
} else if(bits[i] == 0){
y.left = z;
} else{
y.right = z;
}
z.left = nil;
z.right = nil;
x = z;
}
}
答案 0 :(得分:1)
我真的不明白你在for循环中做了什么。例如,我不明白为什么在循环中分配了root
。
使用递归可能有助于使事情更清晰:
public void treeInsert(Integer[] bits, int value) {
treeInsertAux(bits, 0, root, value);
}
private void treeInsertAux(Integer[] bits, int index, Node node, int value) {
if(index == bits.length) {
return;
}
Node child;
if(bits[index] == 0){
child = node.left;
if(child == null) { // first time we pass by this node
child = index == bits.length - 1 ? new Node(value) : new Node();
node.left = child;
// + set parent of child
}
} else {
child = node.right;
if(child == null) { // first time we pass by this node
child = index == bits.length - 1 ? new Node(value) : new Node();
node.right = child;
// + set parent of child
}
}
treeInsertAux(bits, index + 1, child, value)
}