二叉树遍历:前序,中序,后序遍历,层序遍历,可以用递归或者队列,栈来实现!
/**
* 102. Binary Tree Level Order Traversal
* 利用队列实现层序遍历二叉树
* 思路:
* 1.将根节点入队列
* 2.如果队列非空,执行以下步骤:
* a.出队列取得队列的节点,访问该节点
* b.如果左子树非空,将左子树入队列
* c.如果右子树非空,将右子树入队列
* 3.执行完成
*/
public List> levelOrder(TreeNode root) {
List> lists = new ArrayList<>();
if (root == null) {
return lists;
}
Queue queue = new ArrayDeque<>();
queue.add(new LevelNode(root,0));
while (!queue.isEmpty()) {
LevelNode levelNode = queue.poll();
List nodeList = null;
if (levelNode.level == lists.size()) {
nodeList = new ArrayList<>();
lists.add(nodeList);
}else {
nodeList = lists.get(levelNode.level);
}
nodeList.add(levelNode.node.val);
if (levelNode.node.left != null) {
queue.add(new LevelNode(levelNode.node.left,levelNode.level+1));
}
if (levelNode.node.right != null) {
queue.add(new LevelNode(levelNode.node.right,levelNode.level+1));
}
}
return lists;
}
/**
* 144. Binary Tree Preorder Traversal
* 实现: 1.递归实现
* 2.非递归实现:
* 运用栈这种数据结构来模拟递归实现:
* 访问一个节点时,分别对右子树,左子树,以及该节点进行入栈
* 操作!
*/
public List preorderTraversal(TreeNode root) {
List res = new ArrayList<>();
if (root != null) {
Stack stack = new Stack<>();
stack.push(new Commond(root,"go"));
while (!stack.empty()) {
Commond commond = stack.pop();
if (commond.s.equals("print")) {
res.add(commond.node.val);
}else {
if (commond.node.right != null) {
stack.push(new Commond(commond.node.right,"go"));
}
if (commond.node.left != null) {
stack.push(new Commond(commond.node.left,"go"));
}
stack.push(new Commond(commond.node,"print"));
}
}
}
return res;
}
/**
* 94. Binary Tree Inorder Traversal
* @param root
* @return
*/
public List inorderTraversal(TreeNode root) {
List res = new ArrayList<>();
if (root != null) {
Stack stack = new Stack<>();
stack.push(new Commond(root,"go"));
while (!stack.empty()) {
Commond commond = stack.pop();
if (commond.s.equals("print")) {
res.add(commond.node.val);
}else {
if (commond.node.right != null) {
stack.push(new Commond(commond.node.right,"go"));
}
stack.push(new Commond(commond.node,"print"));
if (commond.node.left != null) {
stack.push(new Commond(commond.node.left,"go"));
}
}
}
}
return res;
}
/**
*145. Binary Tree Postorder Traversal
* @param root
* @return
*/
public List postorderTraversal(TreeNode root) {
List res = new ArrayList<>();
if (root != null) {
Stack stack = new Stack<>();
stack.push(new Commond(root,"go"));
while (!stack.empty()) {
Commond commond = stack.pop();
if (commond.s.equals("print")) {
res.add(commond.node.val);
}else {
stack.push(new Commond(commond.node,"print"));
if (commond.node.right != null) {
stack.push(new Commond(commond.node.right,"go"));
}
if (commond.node.left != null) {
stack.push(new Commond(commond.node.left,"go"));
}
}
}
}
return res;
}
根据输入的前序,中序序列重建二叉树
public static TreeNode reConstructBinaryTre(int [] pre,int [] in) {
return build(pre,in,0,pre.length-1,0,in.length-1);
}
public static TreeNode build(int[] pre,int[] in,int pstart,int pend,int istart,int iend){
if(pstart>pend) return null;
int cur = pre[pstart];//根节点
int find = istart;
while(find<=iend){//在中序遍历中查找根节点
if(cur==in[find]) break;
else find++;
}
int len = find-istart;
TreeNode res = new TreeNode(cur);//创建根节点
res.left = build(pre,in,pstart+1,pstart+len,istart,find-1);//创建左子树
res.right = build(pre,in,pstart+len+1,pend,find+1,iend);//创建右子树
return res;
}
/**
* 根据输入的前序,中序序列重建二叉树
* 思路:
* 我们知道,前序遍历的第一个节点为根节点root,中序序列中的root左右两边的节点
* 分别为二叉树的左右子树,根据这个性质,很快就可以还原二叉树
*
* @param pre
* @param in
* @return
*/
public static TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root = re(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
private static TreeNode re(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
if (startPre > endPre|| startIn > endIn) {
return null;
}
TreeNode root = new TreeNode(pre[startPre]);
for (int i = startIn; i <= endIn; i++) {
if (in[i] == pre[startPre]) {
root.left = re(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right = re(pre,startPre+i-startIn+1,endPre,in,i+1,endIn);
}
}
return root;
}