用一串字母创建一棵平衡二叉树

Creating a balanced binary tree with a string of letters

我正在尝试用一串字母创建一棵平衡树。如果你把 "ABCDE" 作为字符串,你的代码应该会给出这样的输出。

输入:"ABCDE"

输出:

 .......................................................
                            +                                                              
            +                              E                              
    +              +              --              --              
A      B      C      D      --      --      --      --      
.......................................................

书上建议我首先创建一个单节点树数组,其根是字符串的每个字符。然后,从每对单节点树中创建一个三节点树,为根创建一个新的 + 节点,这将导致三节点树的森林。

我知道这个问题是最终写出哈夫曼树的垫脚石。

我无法将三节点树放回单节点树的数组中,然后通过组合两个三节点树等来制作七节点树。

下面是我的代码,

import java.util.*; // for Stack class

class StringNode {
  public char iData; // data item (key)
  public StringNode leftChild; // this node's left child
  public StringNode rightChild; // this node's right child

  StringNode(char d) {
    iData = d;
  }

  public void displayNode() // display ourself
  {
    System.out.print('{');
    System.out.print(iData);
    System.out.print("} ");
  }
} // end class Node

class STree {
  private StringNode root; // first node of tree
  public String sequence;

  // -------------------------------------------------------------
  public STree() // constructor
  {
    root = null;
  } // no nodes in tree yet

  public void makeBalanceTree() // creating a balanced tree
  {
    StringNode array[] = new StringNode[sequence.length()];

    for (int i = 0; i < sequence.length(); i++)
      array[i] =
          new StringNode(sequence.charAt(i)); //fill array with node holding each character as key

    STree forest[] = new STree[array.length]; //make a forest of trees
    for (int j = 0; j < array.length; j++) { //store each node as the root of the tree
      forest[j] = new STree();
      forest[j].root = array[j];
    }

    int count = sequence.length();
    while (count == 0) {}
  }

  public void displayTree() {
    Stack globalStack = new Stack();
    globalStack.push(root);
    int nBlanks = 32;
    boolean isRowEmpty = false;
    System.out.println("......................................................");
    while (isRowEmpty == false) {
      Stack localStack = new Stack();
      isRowEmpty = true;

      for (int j = 0; j < nBlanks; j++) System.out.print(' ');

      while (globalStack.isEmpty() == false) {
        StringNode temp = (StringNode) globalStack.pop();
        if (temp != null) {
          System.out.print(temp.iData);
          localStack.push(temp.leftChild);
          localStack.push(temp.rightChild);

          if (temp.leftChild != null || temp.rightChild != null) isRowEmpty = false;
        } else {
          System.out.print("--");
          localStack.push(null);
          localStack.push(null);
        }
        for (int j = 0; j < nBlanks * 2 - 2; j++) System.out.print(' ');
      } // end while globalStack not empty
      System.out.println();
      nBlanks /= 2;
      while (localStack.isEmpty() == false) globalStack.push(localStack.pop());
    } // end while isRowEmpty is false
    System.out.println("......................................................");
  } // end displayTree()
} // end class Tree

public class StringTreeApp {
  public static void main(String[] args) {
    int value;
    STree theTree = new STree();
    theTree.sequence = "ABCDE";
    theTree.makeBalanceTree();
    theTree.displayTree();
  } // end main()
} // end class TreeApp

我认为这本书建议您预先创建一个 StringNode 的数组,这让您的难度变得不必要了。

如果你有一个字符串,你知道 "middle" 字符将成为 iData;它前面的字符将在左树中;它后面的字符将在正确的树中。

因此,您应该能够构建一个 StringNode,如下所示:

StringNode buildStringNode(String sequence) {
  if (sequence.isEmpty()) return null;

  int middlePos = (sequence.length() + 1) / 2;
  char iData = sequence.charAt(middlePos);

  StringNode result = new StringNode(iData);
  result.leftChild = buildStringNode(sequence.substring(0, middlePos));
  result.rightChild = buildStringNode(sequence.substring(middlePos + 1));
  return result;
}

这 "automatically" 将子树与父树组合在一起。你的 makeBalanceTree() 方法就是:

void makeBalanceTree() {
  root = buildStringNode(sequence);
}