横向打印二叉树
问题
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。
…|-12
10-|
…|-8-|
…|…|-7
…|-5-|
…|-4
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
Input
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:
Output
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:
示例
输入
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
输出
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
思路:1.中序遍历递归出每个节点所在行的字符串保存起来,过程中记录当前节点在str中的层数tier和当前节点需要扩展的位置.
2.递归每个节点到它的左右子树所在层
代码
#include <iostream>
#include <string>
using namespace std;
int gN = 0; // 记录数字个数
int gNum[100] = {0}; // 存储排序后的数字
char gMap[1000][1000] = {0};
int gLen[100] = {0}; //
struct node{
int data;
int index;
node *left;
node *right;
node(int d,int i = -1, node *l = NULL, node *r = NULL) : data(d), index(i), left(l), right(r){}
};
void bsort(node *& root, int num){
if(root == NULL){
root = new node(num);
return;
}
if(num < root->data){
bsort(root->left, num);
}else{
bsort(root->right, num);
}
}
void Init(node* root){
if(root == NULL){
return;
}
Init(root->left);
root->index = gN;
gNum[gN++] = root->data;
Init(root->right);
}
void preOrder(node* root, int len){
node *l = root->left;
node *r = root->right;
int idx = gN - 1 - root->index;
if(len > 0){
for(int i = gLen[idx] - 1; i >= 0 ; i--){
gMap[idx][i + len + 2] = gMap[idx][i];
}
for(int i = 0; i < len; i++){
gMap[idx][i] = '.';
}
gMap[idx][len] = '|';
gMap[idx][len + 1] = '-';
gLen[idx] += len + 2;
}
if(l == NULL && r == NULL){ // 没有孩子
// do nothing
}else{ // 如果有孩子
gMap[idx][gLen[idx]] = '-';
gLen[idx]++;
gMap[idx][gLen[idx]] = '|';
if(l != NULL){
preOrder(root->left, gLen[idx]);
}
if(r != NULL){
preOrder(root->right, gLen[idx]);
}
gLen[idx]++;
}
}
void finish(node* child, node *father){
if(child == NULL){
return;
}
if(father != NULL){
int fi = gN - 1 - father->index; // index 与 gNum顺序对应
int ci = gN - 1 - child->index;
if(ci < fi){
for(int i = ci + 1; i < fi; i++){
gMap[i][gLen[fi] - 1] = '|';
}
}else{
for(int i = fi + 1; i < ci; i++){
gMap[i][gLen[fi] - 1] = '|';
}
}
}
finish(child->left, child);
finish(child->right, child);
}
int main()
{
string num;
node *root = NULL;
getline(cin, num, '\n');
string::iterator itr = num.begin();
bool isEnd = false;
int sum = 0;
for(; itr < num.end(); itr++){
if(*itr == ' '){
isEnd = true;
}else{
isEnd = false;
}
if(isEnd){
bsort(root, sum);
sum = 0;
}else{
sum = sum * 10 + *itr - '0';
if(itr + 1 == num.end()){
bsort(root, sum);
}
}
}
Init(root);
for(int i = 0; i < gN; i++){
int tmp = gNum[gN - i - 1];
bool isStart = false;
for(int j = 0; tmp > 0 || tmp < 0; j++){
isStart = true;
for(int k = j; k > 0; k--){
gMap[i][k] = gMap[i][k - 1];
}
gMap[i][0] = tmp % 10 + '0';
gLen[i] = j + 1;
tmp /= 10;
}
if(!isStart){
gMap[i][0] = '0';
gLen[i] = 1;
}
}
preOrder(root, 0);
finish(root, NULL);
for(int i = 0; i < gN; i++){
for(int j = 0; j < gLen[i]; j++){
cout << gMap[i][j];
}cout << endl;
}
return 0;
}