Bottom View of a Binary Tree

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;
	}
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值