二叉树的树形打印

打印一个漂亮的二叉树

在原基础上对二叉树输出的占位符实现动态的改变,使得打印范围得以扩充,但不得不说它还是不够漂亮,除非可以回溯重新校准显示输出。我认为肯定还有更好的解决方法。说我的理解:给定树的高度,可以猜出不同深度处的节点的数量范围并且预期不同深度结点的宽度,实现占位符的合理设置。让我们从功能实现的函数开始吧!

//树形打印函数
int getHeight(const linklist node) {	//二叉树的高度
	int treeHeight = 0;
	if (node != NULL) {
		int leftHeight = getHeight(node->lchild);
		int rightHeight = getHeight(node->rchild);
		treeHeight = leftHeight >= rightHeight? leftHeight + 1:rightHeight + 1;
	}
	return treeHeight;
}

void postorder(linklist p) {
int height = getHeight(p);
	for (int i = 0 ; i < getHeight(p); i ++) {
		printRow(p, height, i);
		height--;
	}
}

上述代码很简单,主要就是*printRow()*函数,现在让我们深入了解:

void printRow(const linklist p, const int height, int depth) {
	vector vec;
	int placeholder=-1;
	getLine(p, depth, vec);
	int flag=height;
	cout << setw(pow(2,flag)-1); // scale setw with depth
	bool toggle = true; // start with left
	if (vec.size() > 1) {
		for (int v=0; v

getLine()执行的操作:它将具有给定相等深度的所有节点存储到vec中。这是代码:

void getLine(const linklist root, int depth, vector& vals) {
	int placeholder=-1;
	if (depth <= 0 && root != NULL) {
		vals.push_back(root->value);
		return;
	}
	if (root->lchild != NULL)
		getLine(root->lchild, depth-1, vals);
	else if (depth-1 <= 0)
		vals.push_back(placeholder);
	if (root->rchild != NULL)
		getLine(root->rchild, depth-1, vals);
	else if (depth-1 <= 0)
		vals.push_back(placeholder);
}

现在回到*printRow()*函数,对于每一行,我们根据二叉树中的深度来设置流宽度,这样有利于对于不同深度的二叉树分配合理的占位符,使得二叉树打印尽可能的美观,这里我对以满二叉树为例讲述占位符的处理:

depth left mid-data
1 2^(n-1)-1 2^n-1
n-3 7 15
n-2 3 7
n-1 1 3
n 0 1

depth:二叉树的深度;left左第一个元素到左临界的占位符(空格);mid-data:各层相邻数据间隔之间的占位符

在深度稍大的时候,这看起来就不那么漂亮,希望你们能完善吧。只要树大致平衡且小(<20项),它应该变得很好。这里需要占位符才能正确对齐“/”和“\”字符。另外,当通过getLine()获取行时,如果指定深度处没有任何节点,则插入占位符。占位符可以设置为任何标识。不过,这不是很完善,因为占位符里面存储的可能是有效的节点值。

顺序插入数据:10 5 1 7 12 15

     10
  /      \
  5     12
/  \     \
1  7    15

你可能感兴趣的:(数据结构)