Given a Binary Tree, we need to print the bottom view from left to right. A node x is there in output if x is the bottommost node at its horizontal distance. Horizontal distance of left child of a node x is equal to horizontal distance of x minus 1, and that of right child is horizontal distance of x plus 1.
Examples:
20 / \ 8 22 / \ \ 5 3 25 / \ 10 14
For the above tree the output should be 5, 10, 3, 14, 25.
If there are multiple bottom-most nodes for a horizontal distance from root, then print the later one in level traversal. For example, in the below diagram, 3 and 4 are both the bottom-most nodes at horizontal distance 0, we need to print 4.
20 / \ 8 22 / \ / \ 5 3 4 25 / \ 10 14
For the above tree the output should be 5, 10, 4, 14, 25.
解决思路:算出二叉树最左边节点的距离,在算出二叉树最右边节点的距离,可以得出这棵二叉树所有节点的距离范围,如果根节点的水平距离为9,那么上边两个二叉树的距离范围是[-2, 2]。也就是说,输出节点应该有5个。那么怎么算每个节点的水平距离?首先要层次遍历二叉树,根据规则,根节点的左边孩子的水平距离是根节点水平距离减1,根节点右边孩子水平距离是根节点水平距离加1,层次遍历二叉树过程中,就算出了每个节点的水平距离,但是要求输出的水平距离只对应一个节点,所以要留下水平距离值相同的最后一个节点,用map可以做到。
#include <map>
#include <vector>
#include <iostream>
using namespace std;
typedef struct TreeNode {
int data;
struct TreeNode* lchild;
struct TreeNode* rchild;
}TreeNode;
TreeNode* createNode(int data) {
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
if (NULL == node)
return NULL;
node->data = data;
node->lchild = NULL;
node->rchild = NULL;
return node;
}
int getLeftMostDistance(TreeNode* root) {
if (NULL == root)
return 0;
int left = 0;
if (root->lchild) {
left = getLeftMostDistance(root->lchild) - 1;
}
return left;
}
int getRightMostDistance(TreeNode* root) {
if (NULL == root)
return 0;
int right = 0;
if (root->rchild) {
right = getRightMostDistance(root->rchild) + 1;
}
return right;
}
void printMap(map<int, TreeNode*> mp) {
map<int, TreeNode*>::iterator iter;
iter = mp.begin();
while (iter != mp.end()) {
TreeNode* node = iter->second;
cout << node->data << " ";
iter ++;
}
cout << endl;
}
void getBottommostNode(TreeNode* root) {
vector<int> disVec;
vector<TreeNode*> vec;
map<int, TreeNode*> mp;
vec.push_back(root);
disVec.push_back(0);
mp.insert(map<int, TreeNode*>::value_type(0, root));
int curPos = 0;
while (curPos < vec.size()) {
int size = vec.size();
while (curPos < size) {
int dist = disVec[curPos];
TreeNode* node = vec[curPos];
map<int, TreeNode*>::iterator iter;
if (node->lchild) {
vec.push_back(node->lchild);
disVec.push_back(dist - 1);
iter = mp.find(dist - 1);
if (iter != mp.end()) {
mp.erase(iter);
}
mp.insert(map<int, TreeNode*>::value_type(dist - 1, node->lchild));
}
if (node->rchild) {
vec.push_back(node->rchild);
disVec.push_back(dist + 1);
iter = mp.find(dist + 1);
if (iter != mp.end()) {
mp.erase(iter);
}
mp.insert(map<int, TreeNode*>::value_type(dist + 1, node->rchild));
}
curPos++;
}
}
cout << endl;
printMap(mp);
}
TreeNode* createTree() {
TreeNode* root = createNode(20);
root->lchild = createNode(8);
root->rchild = createNode(22);
root->lchild->lchild = createNode(5);
root->lchild->rchild = createNode(3);
root->rchild->lchild = createNode(4);
root->rchild->rchild = createNode(25);
root->lchild->rchild->lchild = createNode(10);
root->lchild->rchild->rchild = createNode(14);
return root;
}
int main(int argc, char* argv[]) {
TreeNode* root = createTree();
getBottommostNode(root);
return 0;
}
竖向遍历二叉树
#include <map>
#include <vector>
#include <iostream>
using namespace std;
typedef struct TreeNode {
int data;
struct TreeNode* lchild;
struct TreeNode* rchild;
}TreeNode;
TreeNode* createNode(int data) {
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
if (NULL == node)
return NULL;
node->data = data;
node->lchild = NULL;
node->rchild = NULL;
return node;
}
int getLeftMostDistance(TreeNode* root) {
if (NULL == root)
return 0;
int left = 0;
if (root->lchild) {
left = getLeftMostDistance(root->lchild) - 1;
}
return left;
}
int getRightMostDistance(TreeNode* root) {
if (NULL == root)
return 0;
int right = 0;
if (root->rchild) {
right = getRightMostDistance(root->rchild) + 1;
}
return right;
}
void printMap(map<int, TreeNode*> mp) {
map<int, TreeNode*>::iterator iter;
iter = mp.begin();
while (iter != mp.end()) {
TreeNode* node = iter->second;
cout << node->data << " ";
iter ++;
}
cout << endl;
}
void printVecs(vector<vector<TreeNode*> > vecs, int size) {
int i, j;
vector<TreeNode*>::iterator iter;
for (i = 0; i < size; i++) {
for (j = 0; j < vecs[i].size(); j++)
cout << vecs[i][j]->data << " ";
cout << endl;
}
}
void traverseVertically(TreeNode* root) {
vector<int> disVec;
vector<TreeNode*> vec;
vec.push_back(root);
disVec.push_back(0);
int left = getLeftMostDistance(root);
int right = getRightMostDistance(root);
vector<vector<TreeNode*> > vecs;
for (int i = 0; i < right - left + 1; i++) {
vector<TreeNode*> v;
vecs.push_back(v);
}
vecs[0 - left].push_back(root);
int curPos = 0;
while (curPos < vec.size()) {
int size = vec.size();
while (curPos < size) {
int dist = disVec[curPos];
TreeNode* node = vec[curPos];
if (node->lchild) {
vec.push_back(node->lchild);
disVec.push_back(dist - 1);
vecs[dist - 1 - left].push_back(node->lchild);
}
if (node->rchild) {
vec.push_back(node->rchild);
disVec.push_back(dist + 1);
vecs[dist + 1 - left].push_back(node->rchild);
}
curPos++;
}
}
cout << endl;
printVecs(vecs, right - left + 1);
}
TreeNode* createTree() {
TreeNode* root = createNode(20);
root->lchild = createNode(8);
root->rchild = createNode(22);
root->lchild->lchild = createNode(5);
root->lchild->rchild = createNode(3);
root->rchild->lchild = createNode(4);
root->rchild->rchild = createNode(25);
root->lchild->rchild->lchild = createNode(10);
root->lchild->rchild->rchild = createNode(14);
return root;
}
int main(int argc, char* argv[]) {
TreeNode* root = createTree();
traverseVertically(root);
return 0;
}
java 版本实现:
package com.t;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
class TreeNode {
public int value;
public TreeNode lchild;
public TreeNode rchild;
public TreeNode(int value) {
this.value = value;
}
}
public class Traverse {
public static void main(String []args) {
TreeNode root = createTree();
verticalTraverse(root);
}
public static TreeNode createTree() {
TreeNode root = new TreeNode(20);
root.lchild = new TreeNode(8);
root.rchild = new TreeNode(22);
root.lchild.lchild = new TreeNode(5);
root.lchild.rchild = new TreeNode(3);
root.lchild.rchild.lchild = new TreeNode(10);
root.rchild.lchild = new TreeNode(4);
root.rchild.rchild = new TreeNode(25);
root.rchild.lchild.rchild = new TreeNode(14);
return root;
}
public static void verticalTraverse(TreeNode root) {
if (null == root)
return;
int pos = 0;
Map<Integer, ArrayList<TreeNode>> map = new HashMap<Integer, ArrayList<TreeNode>>();
verticalTraverseUtil(root, map, pos);
Map<Integer, ArrayList<TreeNode>> resultMap = sortMapByKey(map);
StringBuilder sb = new StringBuilder();
for (ArrayList<TreeNode> list : resultMap.values()) {
for (TreeNode node : list) {
sb.append(node.value).append(" ");
}
sb.append("\n");
}
System.out.println(sb.toString());
}
public static void verticalTraverseUtil(TreeNode root, Map<Integer, ArrayList<TreeNode>> map, int pos) {
//in order traverse to ensure the correct output
ArrayList<TreeNode> col = map.get(pos);
if (null == col) {
col = new ArrayList<TreeNode>();
map.put(pos, col);
}
col.add(root);
if (null != root.lchild) {
verticalTraverseUtil(root.lchild, map, pos - 1);
}
if (null != root.rchild) {
verticalTraverseUtil(root.rchild, map, pos + 1);
}
}
private static Map<Integer, ArrayList<TreeNode>> sortMapByKey(Map<Integer, ArrayList<TreeNode>> map) {
Map<Integer, ArrayList<TreeNode>> sortMap = new TreeMap<Integer, ArrayList<TreeNode>>(new Comparator<Integer>() {
public int compare(Integer key1, Integer key2) {
return key1.compareTo(key2);
}
});
sortMap.putAll(map);
return sortMap;
}
}