打印二叉树边界节点

题目:打印二叉树的边界节点(注:片文全部来自左神写得书,见文末注解)
给定一颗二叉树的头结点head,按照如下两种标准分别实现二叉树边界点的逆时针打印
标准一:
1、头结点为边界节点
2、叶节点为边界节点
3、如果节点在其所在的层中是最左或是最右的,那么也是边界节点
标准二:

1、头结点为边界节点
2、叶节点为边界节点
3、树左边界延伸下去的路径为边界节点
4、树右边界延伸下去的路径为边界节点

下面借鉴了左神讲述的内容进行模拟了一下,具体过程,左神推敲如下(我也是直接搬的左神的思路,注明):
标准一:
1、得到二叉树每一层上最左边和最右边的节点
2、从上到下打印所有层中的最左节点
3、先序遍历二叉树,打印那些不属于某一层最左或最右的节点
4、从上到下打印所有层中的最右节点
标准二:
1、从头节点开始往下寻找,只要找到第一个既有左孩子又有右孩子的节点,直接进入步骤2
,记为h。在这个过程中,找过的节点直接打印。
2、h的左子树先进入步骤3的打印过程;h的右子树再进入步骤4的打印过程,最后返回
3、打印左边界的延伸路径以及h左子树上所有的叶节点
4、打印右边界的延伸路径以及h右子树上所有的叶节点
按照标准1打印:1,2,4,7,11,13,14,15,16,12,10,6,3
按照标准2打印: 1,2,4,7,13,14,15,16,10,6,3

这里写图片描述

java代码实现如下

package com.gcp.www;

/**
* 标准1
* 头结点为边界节点
* 叶节点为边界节点
* 如果节点在其所在的层中是最左还是最右,那么也是节点
* @author chaplinJ
*标准2
*头结点为边界节点
*叶节点为边界节点
*树左边界延伸下去的路径为边界节点
*树右边界延伸下去的路径是边界节点
*/
class Node{
public int value;
public Node left;
public Node right;
public Node(int data){
this.value = data;
}
}
public class PrintBinaryTreeBoundary {

/**
 * 按照标准1打印二叉树边界节点
 * @param head
 */
public void printBitTree1(Node head){ //按照标准1打印二叉树的边界节点

    if(head == null){
        return;
    }
    int height = getHeight(head,0); //获取树的高度
    Node[][] edgeTo = new Node[height][2];
    setEdgeMap(head, 0, edgeTo);
    //打印做边界节点
    for(int i = 0 ; i < edgeTo.length;i++){
        System.out.print(edgeTo[i][0].value + " ");
    }
    //打印叶子节点
    printLeafNotInMap(head,0,edgeTo);
    //打印右节点但不是做节点的
    for(int i = height - 1; i >=0;i--){
        if(edgeTo[i][0] != edgeTo[i][1]){
            System.out.print(edgeTo[i][1].value + " ");
        }
    }
}

/**
 * 按照标准2打印二叉树的边界节点
 * @param head
 */
public void printBitTree2(Node head){ //按照标准2打印二叉树的边界节点

    if(head == null){
        return;
    }
    System.out.print(head.value + " ");
    if(head.left != null && head.right != null){ //
        printLeftEdge(head.left,true);
        printRightEdge(head.right, true);
    }else{
        printBitTree2(head.left != null?head.left : head.right);
    }
    System.out.println();
}

public void printLeftEdge(Node h,boolean print){
    if(h == null){
        return;
    }
    if(print || (h.left == null && h.right == null)){
        System.out.print(h.value + " ");
    }
    printLeftEdge(h.left, print);
    printLeftEdge(h.right, print && h.left == null ? true:false);
}

public void printRightEdge(Node h,boolean print){
    if(h == null){
        return;
    }
    printRightEdge(h.left, print && h.right == null?true:false);
    printRightEdge(h.right, print);

    if(print || (h.left == null && h.right == null)){
        System.out.print(h.value +" ");
    }
}

private void setEdgeMap(Node head,int l,Node[][] edgeTo){
    if(head == null){
        return;
    }
    edgeTo[l][0] = (edgeTo[l][0] == null?head:edgeTo[l][0]);
    edgeTo[l][1] = head;
    setEdgeMap(head.left,l+1,edgeTo);
    setEdgeMap(head.right,l+1,edgeTo);
}

private void printLeafNotInMap(Node head,int l,Node[][] edgeTo){
    if(head == null){
        return;
    }
    if(head.left == null && head.right == null && edgeTo[l][0] != head && head!= edgeTo[l][1]){
        System.out.print(head.value + " ");
    }
    printLeafNotInMap(head.left, l+1, edgeTo);
    printLeafNotInMap(head.right, l+1, edgeTo);
}

/**
 * 获取树的高度
 * @param head
 * @param l
 * @return
 */
private int getHeight(Node head,int l){ 
    if(head == null){
        return l;
    }else
        return Math.max(getHeight(head.left,l+1), getHeight(head.right,l + 1));
}

public static void main(String[] args) {
    Node node1 = new Node(1);
    Node node2 = new Node(2);
    Node node3 = new Node(3);
    Node node4 = new Node(4);
    Node node5 = new Node(5);
    Node node6 = new Node(6);
    Node node7 = new Node(7);
    Node node8 = new Node(8);
    Node node9 = new Node(9);
    Node node10 = new Node(10);
    Node node11 = new Node(11);
    Node node12 = new Node(12);
    Node node13 = new Node(13);
    Node node14 = new Node(14);
    Node node15 = new Node(15);
    Node node16 = new Node(16);
    node1.right = node3;
    node1.left = node2;
    node2.right = node4;
    node4.left = node7;
    node4.right = node8;
    node8.right = node11;
    node11.left = node13;
    node11.right = node14;
    node3.left = node5;
    node3.right = node6;
    node5.left = node9;
    node5.right = node10;
    node9.left = node12;
    node12.left = node15;
    node12.right = node16;
    new PrintBinaryTreeBoundary().printBitTree1(node1);
    System.out.println();
    new PrintBinaryTreeBoundary().printBitTree2(node1);
}

}

注:文章算法内容来自做左程云—IT名企算法与数据结构题目最优解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值