public class BinaryTree {
private TreeNode root=null; //根节点;
public BinaryTree(){
root=new TreeNode(1,"A"); //初始化下标为1的根节点
}
/*
* 构建二叉树 -->把子节点一个个的加上去
* A
* B C
* D E F
*/
public void createBinaryTree(){
TreeNode nodeB=new TreeNode(2,"B");
TreeNode nodeC=new TreeNode(3,"C");
TreeNode nodeD=new TreeNode(4,"D");
TreeNode nodeE=new TreeNode(5,"E");
TreeNode nodeF=new TreeNode(6,"F");
root.leftChild=nodeB;
root.rightChild=nodeC;
nodeB.leftChild=nodeD;
nodeB.rightChild=nodeE;
nodeC.rightChild=nodeF;
}
/*
* 求二叉树的深度 简单举例: A
* B C
* D 此举例深度为3
*/
public int getHeight(){
return getHeight(root);
}
private int getHeight(TreeNode root2) {
if(root2 == null){
return 0;
}
else{ //迭代,每迭代一层, 表达式 getHeight(root2.leftChild)+1
int i = getHeight(root2.leftChild);
int j = getHeight(root2.rightChild);
return (i < j) ? j+1 : i+1;
}
}
/*
* 获取二叉树的节点数 举例: A
* B C
*/
public int getSize(){
return getSize(root);
}
private int getSize(TreeNode root2) {
if(root2 == null){
return 0;
}
else{
return 1 + getSize(root2.leftChild) + getSize(root2.rightChild);
}
}
/*
* 二叉树的前序遍历(根->左 ->右) -- 迭代实现
*/
public void preOrder(TreeNode node){
if(node == null){
return;
}
else{
System.out.println("preOrder data: "+node.getData());
preOrder(node.leftChild);
preOrder(node.rightChild);
}
}
/*
*
* A
* B C
* D E # F
* # # # # # #
*
* 前序遍历: A B D # # E # # C # F # #
*/
/*
* 前序遍历 --非递归实现 核心思想: 每一次遍历 都记住他的根节点 压入子节点 弹出根节点
* 注:把B节点(包括下面的)那一坨遍历完之后,由于我们还记得之前有个根节点叫A,我们把那一坨当做一个大节点
* 把C当做右节点,把A当做根节点,因此把B那一大坨遍历完后还要找C节点(A的右节点)
* 同样地,当遍历至B节点,D节点遍历结束后,你为啥去遍历E节点呢? 是因为你还记得有个根节点B存在
*/
public void nonRecOrder(TreeNode node){
if(node == null){
return;
}
Stack<TreeNode> stack=new Stack<TreeNode>();
stack.push(node); //先压入根节点
while( !stack.isEmpty()){
//出栈和入栈
TreeNode n=stack.pop(); //弹出根节点
System.out.println("nonReOrder data: "+n.getData());
//压入子节点
if(n.rightChild != null){
stack.push(n.rightChild);
}
if(n.leftChild != null){
stack.push(n.leftChild);
}
}
}
/*
* 二叉树的中序遍历 左->根->右
*/
public void midOrder(TreeNode node){
if(node == null){
return;
}
else{
midOrder(node.leftChild);
System.out.println("midOrder data: "+node.data);
midOrder(node.rightChild);
}
}
/**
* 迭代实现,首先依次将左子节点全部加入栈中,所以第一个while循环后栈顶元素对应一个子树的最
* 左子节点,然后将该元素出栈加入list,并判断该元素的遍历该节点的右子树。
*/
//中序遍历的非递归实现
public void nonRecInOrder(TreeNode p){
Stack<TreeNode> stack =new Stack<TreeNode>();
TreeNode node =p;
while(node!=null || stack.size()>0){
//存在左子树
while(node!=null){
stack.push(node);
node=node.leftChild;
}
//栈非空
if(stack.size()>0){
node=stack.pop();
System.out.println("nonReOrder data: "+node.getData());
node=node.rightChild;
}
}
}
/*
* 二叉树的后序遍历 左->右->根
*/
public void postOrder(TreeNode node){
if(node == null){
return;
}
else{
postOrder(node.leftChild);
postOrder(node.rightChild);
System.out.println("postOrder data: "+node.data);
}
}
/**
* 使用栈实现,出栈得到节点顺序为根右左,每次向list最开头插入元素
* A
* B C
*/
public List<String> postOrderTraversal(TreeNode root) {
List<String> result = new ArrayList<String>();
if(root == null)
return result;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root); //首先将根节点压栈
while(!stack.isEmpty()) {
TreeNode ele = stack.pop(); //首先出栈的为根节点,其后先出右子节点,后出左子节点
if(ele.leftChild != null)
stack.push(ele.leftChild); //将左子节点压栈
if(ele.rightChild != null) {
stack.push(ele.rightChild); //将右子节点压栈
}
result.add(0,ele.data); //因为出栈顺序为“根右左”,所以需要每次将元素插入list开头
}
return result;
}
public class TreeNode{ //树节点
private int index;
private String data;
private TreeNode leftChild;
private TreeNode rightChild;
public TreeNode(int index,String data){ //构造方法
this.index=index;
this.data=data;
this.leftChild=null;
this.rightChild=null;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public TreeNode getLeftChild() {
return leftChild;
}
public void setLeftChild(TreeNode leftChild) {
this.leftChild = leftChild;
}
public TreeNode getRightChild() {
return rightChild;
}
public void setRightChild(TreeNode rightChild) {
this.rightChild = rightChild;
}
}
public static void main(String[] args) {
BinaryTree binaryTree=new BinaryTree();
binaryTree.createBinaryTree();
int height=binaryTree.getHeight();
System.out.println("treeHeight: "+height);
//节点数
int size=binaryTree.getSize();
System.out.println("treeSize: "+size);
//binaryTree.preOrder(binaryTree.root); //前序遍历 递归:
//System.out.println("******************");
//binaryTree.midOrder(binaryTree.root); //中序遍历 递归
//System.out.println("*************");
binaryTree.postOrder(binaryTree.root); //后序遍历 递归
//System.out.println("*********");
//前序遍历 非迭代实现
//binaryTree.nonRecOrder(binaryTree.root);
//中序遍历 非递归实现
//binaryTree.nonRecInOrder(binaryTree.root);
//后续 遍历 非递归实现
//System.out.println(binaryTree.postOrderTraversal(binaryTree.root));
}
/* 2. 二叉树的建立 */
/*
* 通过前序遍历的数据序列反向生成二叉树
* A
* B C
* D E # F
* # # # # # #
*
* 前序遍历: A B D # # E # # C # F # #
*/
public void createBinaryTreePre(ArrayList<String> data){
createBinaryTree(data.size(),data);
}
private TreeNode createBinaryTree(int size, ArrayList<String> data) {
if(data.size() == 0){
return null;
}
String d=data.get(0);
TreeNode node;
int index= size - data.size();
if(d.equals("#")){
node=null;
return node;
}
node=new TreeNode(index,d);
if(index == 0){
//创建根节点
root=node;
data.remove(0);//每创建一个节点就去除头结点
}else{
data.remove(0);
node.leftChild = createBinaryTree(size,data);
node.rightChild= createBinaryTree(size,data);
}
return node;
}
}
另一种二叉树的建立:
public static void main(String[] args) {
CreateBinaryTree binaryTree=new CreateBinaryTree();
ArrayList<String> data=new ArrayList<>();
String[] dataArray=new String[]{"A","B","D","#","#","E",
"#","#","C","#","F","#","#"};
for(String d: dataArray){
data.add(d);
}
binaryTree.createBinaryTreePre(data);
}
/* 2. 二叉树的建立 */
/*
* 通过前序遍历的数据序列反向生成二叉树
* A
* B C
* D E # F
* # # # # # #
*
* 前序遍历: A B D # # E # # C # F # #
* 0 1 2 3 4 5 6 7 ..... 12
*/
public void createBinaryTreePre(ArrayList<String> data){
createBinaryTree(data.size(),data);
}
/* A
* # B
*/
private TreeNode createBinaryTree(int size, ArrayList<String> data) {
if(data.size() == 0){
return null;
}
String d=data.get(0);
TreeNode node;
int index= size - data.size();
if(d.equals("#")){
node=null;
data.remove(0); //即使是井号也要remove掉,因为它也占一个长度
return node;
}
node=new TreeNode(index,d);
if(index == 0){
//创建根节点
root=node;
}
data.remove(0);
node.leftChild = createBinaryTree(size,data);
node.rightChild= createBinaryTree(size,data);
return node;
}