Java 使用文本打印二叉搜索树
我想以以下格式打印二进制搜索树:Java 使用文本打印二叉搜索树,java,binary-search-tree,Java,Binary Search Tree,我想以以下格式打印二进制搜索树: 4 / \ / \ 2 5 / \ / \ 1 3 4 6 我想我必须得到树的深度,然后,对于每个级别,在每个元素前后打印一些空格 public void printTree(BSTNode T, int depth) { for (int i = 1; i <= depth; i++){ //then what? } 您可以做的是获取一个队列,并在每个级别遍历时
4
/ \
/ \
2 5
/ \ / \
1 3 4 6
我想我必须得到树的深度,然后,对于每个级别,在每个元素前后打印一些空格
public void printTree(BSTNode T, int depth) {
for (int i = 1; i <= depth; i++){
//then what?
}
您可以做的是获取一个队列,并在每个级别遍历时使用每个级别的节点对其进行初始化。 在此之后,弹出每个元素,打印它并将其推送到左侧和右侧节点的队列中。
像这样继续遍历到整个深度,您将能够以所需的格式打印树。有一点是肯定的:这不是一个容易的问题。这是我的方法 首先,让我们把递归搞清楚。我想做的是打印节点的左子树,然后打印右子树,然后以某种方式将这两个子树组合起来以获得最终结果。为此,我需要一个用于这些中间值的数据类:
public class TreeString {
private List<String> lines;
private int columnCount;
private int rootColumn;
public TreeString(List<String> lines, int columnCount, int rootColumn) {
this.lines = new ArrayList<>(lines);
this.columnCount = columnCount;
this.rootColumn = rootColumn;
}
/** @return the number of lines */
public int getLineCount() {
return lines.size();
}
/** @return the number of columns */
public int getColumnCount() {
return columnCount;
}
/** @return the index of the column containing the center of the root */
public int getRootColumn() {
return rootColumn;
}
/** @return the number of columns to the right of the column containing the center of the root */
public int getRootColumnFromRight() {
return getColumnCount() - (getRootColumn() + 1);
}
/** @return the line at {@code index} */
public String getLine(int index) {
return lines.get(index);
}
}
将由以下三重约束表示:
lines = new ArrayList<>(Arrays.asList(" 4 ", " / \\ ", " 2 5", " / \\ ", "1 3 "));
columnCount = 7;
rootColumn = 4;
现在,我们来看一下主要活动:
public String spaces(int numSpaces) {
String string = "";
for (int i = 0; i < numSpaces; ++i) {
string += " ";
}
return string;
}
public TreeString combineTreeStrings(TreeString parent, TreeString left, TreeString right) {
if (left == null && right == null) {
return parent;
}
// the number of lines between the bottom of parent and the tops of left and right
// also the number of columns between parent's root column and the root columns of left or right
int verticalGap = 1;
// the number of columns between the left end of right and the right end of left
int middleGap = 0;
if (left != null && right != null) {
verticalGap = Math.max(verticalGap, (left.getRootColumnFromRight() + 1 + right.getRootColumn()) / 2);
middleGap = (verticalGap - left.getRootColumnFromRight()) + 1 + (verticalGap - right.getRootColumn());
}
// the number of columns between the left end of left (or right, if left is null) and the left end of the result
int lowerLeftGap;
// the number of columns between the left end of parent and the left end of the result
int upperLeftGap;
if (left != null) {
lowerLeftGap = Math.max(0, parent.getRootColumn() - verticalGap - 1 - left.getRootColumn());
upperLeftGap = Math.max(0, left.getRootColumn() + 1 + verticalGap - parent.getRootColumn());
} else {
lowerLeftGap = Math.max(0, parent.getRootColumn() + 1 + verticalGap - right.getRootColumn());
upperLeftGap = Math.max(0, right.getRootColumn() - verticalGap - 1 - parent.getRootColumn());
}
// the number of columns between the right end of the result and the right end of right (or left, if right is null)
int lowerRightGap;
// the number of columns between the right end of the result and the right end of parent
int upperRightGap;
if (right != null) {
lowerRightGap = Math.max(0, -right.getRootColumnFromRight() - 1 - verticalGap + parent.getRootColumnFromRight());
upperRightGap = Math.max(0, -parent.getRootColumnFromRight() + verticalGap + 1 + right.getRootColumnFromRight());
} else {
lowerRightGap = Math.max(0, -left.getRootColumnFromRight() + verticalGap + 1 + parent.getRootColumnFromRight());
upperRightGap = Math.max(0, -parent.getRootColumnFromRight() - 1 - verticalGap + left.getRootColumnFromRight());
}
List<String> lines = new ArrayList<>();
// parent lines
for (int i = 0; i < parent.getLineCount(); ++i) {
lines.add(spaces(upperLeftGap) + parent.getLine(i) + spaces(upperRightGap));
}
// slash and backslash lines
for (int i = 0; i < verticalGap; ++i) {
String leftLeg;
if (left != null) {
leftLeg = "/";
} else if (upperLeftGap > 0) {
leftLeg = " ";
} else {
leftLeg = "";
}
String rightLeg;
if (right != null) {
rightLeg = "\\";
} else if (upperRightGap > 0) {
rightLeg = " ";
} else {
rightLeg = "";
}
int numLeftSpaces = upperLeftGap + parent.getRootColumn() - leftLeg.length() - i;
int numRightSpaces = upperRightGap + parent.getRootColumnFromRight() - rightLeg.length() - i;
lines.add(spaces(numLeftSpaces) + leftLeg + spaces(i + 1 + i) + rightLeg + spaces(numRightSpaces));
}
// left and right lines
for (int i = 0; i < Math.max(left == null ? 0 : left.getLineCount(), right == null ? 0 : right.getLineCount()); ++i) {
String leftLine;
if (left == null) {
leftLine = "";
} else if (i >= left.getLineCount()) {
leftLine = spaces(left.getColumnCount());
} else {
leftLine = left.getLine(i);
}
String rightLine;
if (right == null) {
rightLine = "";
} else if (i >= right.getLineCount()) {
rightLine = spaces(right.getColumnCount());
} else {
rightLine = right.getLine(i);
}
lines.add(spaces(lowerLeftGap) + leftLine + spaces(middleGap) + rightLine + spaces(lowerRightGap));
}
return new TreeString(lines, upperLeftGap + parent.getColumnCount() + upperRightGap, upperLeftGap + parent.getRootColumn());
}
公共字符串空间(int numSpaces){
字符串=”;
for(int i=0;i0){
左腿=”;
}否则{
左腿=”;
}
串右腿;
if(右!=null){
右腿=“\\”;
}否则如果(右上方间隙>0){
右腿=”;
}否则{
右腿=”;
}
int numLeftSpaces=upperLeftGap+parent.getRootColumn()-leftLeg.length()-i;
int numRightSpaces=upperRightGap+parent.getRootColumnFromRight()-rightLeg.length()-i;
添加(空格(numLeftSpaces)+左腿+空格(i+1+i)+右腿+空格(numRightSpaces));
}
//左右线
对于(int i=0;i=left.getLineCount()){
leftLine=spaces(left.getColumnCount());
}否则{
leftLine=left.getLine(i);
}
字符串右行;
if(right==null){
右行=”;
}else如果(i>=right.getLineCount()){
rightLine=空格(right.getColumnCount());
}否则{
rightLine=right.getLine(i);
}
添加(空格(lowerRightGap)+左行+空格(middleGap)+右行+空格(lowerRightGap));
}
返回新的TreeString(行,upperLeftGap+parent.getColumnCount()+upperRightGap,upperLeftGap+parent.getRootColumn());
}
希望这能解决你的问题!如果有什么办法可以解决这个问题,请不要犹豫发表评论。我已经找到了一个没有斜杠的解决方案。先过树宽;在ArrayList中存储在某个级别上找到的所有值;在一行上打印值,根据级别使用缩进和间距;转到下一个级别并存储该级别的所有值,依此类推
注释块用于斜杠
给定二进制搜索树中的输入10、5、15、1、7、20、12、6、2、8,则不带斜杠的输出为
10
5 15
1 7 12 20
2 6 8
10
/ \
/ \
/ \
/ \
5 15
/ \ / \
/ \ / \
1 7 12 20
/ \ / \ / \ / \
2 6 8
用斜线是
10
5 15
1 7 12 20
2 6 8
10
/ \
/ \
/ \
/ \
5 15
/ \ / \
/ \ / \
1 7 12 20
/ \ / \ / \ / \
2 6 8
带有斜杠的解决方案的输出并不完美,需要改进
10
/ \
/ \
/ \
/ \
5 15
/ \ / \
/ \ / \
1 7 12 20
/ \ / \ / \ / \
2 6 8
public void printTree(BSTNode T, int depth) {
int indent, spacing, numberOfSlashes;
ArrayList value = new ArrayList();
for (int d = 1; d <= depth; d++){
value.clear();
getLevel(value, T, d);
indent = (int) (Math.pow(2, (depth-d)) - 1);
spacing = (int) (Math.pow(2, (depth-d+1)) - 1);
for (int i = 0; i < indent; i++){
System.out.print(" ");
}
for (Object x: value){
System.out.print(x);
for (int i = 0; i < spacing; i++){
System.out.print(" ");
}
}
System.out.println();
/*if (depth != d){
numberOfSlashes = (int) Math.pow(2, (depth-d-1));
printSlash(value, numberOfSlashes, indent, 1);
}*/
}
}
private void printSlash(ArrayList v, int slashes, int indent, int s) {
for (int z = 0; z < slashes; z++){
for (int index = 0; index < v.size(); index++){
for (int i = 0; i < indent; i++){
System.out.print(" ");
}
System.out.print("/");
for (int space = 0; space < s; space++){
System.out.print(" ");
}
System.out.print("\\");
for (int nextSpace = 0; nextSpace < indent; nextSpace++){
System.out.print(" ");
}
}
System.out.println();
indent = indent - 1;
s = s + 2;
}
}
private void getLevel(ArrayList v, BSTNode T, int l) {
if (T == null)
v.add(" ");
else if (l == 1)
v.add(T.getValue());
else if (l > 1){
getLevel(v, T.getLeft(), l-1);
getLevel(v, T.getRight(), l-1);
}
}