java 实现linux tree,Java实现链式存储的二叉树

二叉树的定义:

二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。

二叉树的遍历方式主要有:先序遍历(NLR),中序遍历(LNR),后序遍历(LRN),和层次遍历。

注意:

由二叉树的先序序列和中序序列可以唯一地确定一颗二叉树;

由二叉树的后序序列和中序序列可以唯一地确定一颗二叉树;

由二叉树的层序序列和中序序列可以唯一地确定一棵二叉树;

但,由二叉树的先序序列和后序序列无法唯一地确定一棵二叉树。

Java实现链式存储的二叉树以及其各种遍历算法:

树节点:

public class TreeNode {

private E data;  //数据域

private TreeNode lchild;  //左孩子

private TreeNode rchild;  //右孩子

TreeNode(){}

TreeNode(E e){

this.data = e;

}

TreeNode(E data,TreeNode lchild, TreeNode rchild){

this.data = data;

this.lchild = lchild;

this.rchild = rchild;

}

public void setData(E data){

this.data = data;

}

public E getData(){

return this.data;

}

public void setLchild(TreeNode lchild){

this.lchild = lchild;

}

public TreeNode getLchild(){

return this.lchild;

}

public void setRchild(TreeNode rchild){

this.rchild = rchild;

}

public TreeNode getRchild(){

return this.rchild;

}

}

二叉树的Java实现:

import java.util.LinkedList;

import java.util.List;

import java.util.Queue;

import java.util.Stack;

/**

* @author Cherish

* 二叉树的链式存储结构

* @param

*/

public class BinaryTree {

private TreeNode root;  //根节点

private List nodeList = null;  //二叉树节点的链式结构

public BinaryTree(){

}

public BinaryTree(TreeNode root){

this.root = root;

}

//把一个数组转化为一颗完全二叉树

public TreeNode buildTree(E[] array){

nodeList = new LinkedList();

//将数组中的元素依次转换为TreeNode节点,存放于链表中

for(int i=0; i< array.length; i++){

nodeList.add(new TreeNode(array[i]));

}

//对前(array.length / 2 - 1)个父节点,按照父节点与孩子节点的数字关系建立完全二叉树

//对完全二叉树,按从上到下,从左到右的顺序依次编号0,1,2,3....N,则i>0的节点,其左孩子为(2*i+1),

//其右孩子为(2*i+2)

for(int j=0; j < (array.length/2-1);j++){

//左孩子

nodeList.get(j).setLchild(nodeList.get(j*2+1));

//右孩子

nodeList.get(j).setRchild(nodeList.get(j*2+2));

}

//最后一个父节点:因为最后一个父节点可能没有右孩子,所以单独处理

int index = array.length/2 -1;

//左孩子

nodeList.get(index).setLchild(nodeList.get(index*2+1));

//右孩子:如果数组的长度为奇数才有右孩子

if(array.length % 2 == 1){

nodeList.get(index).setRchild(nodeList.get(index*2+2));

}

root=nodeList.get(0); //设置根节点

return root;

}

//得到树的高度

public int height(TreeNode node){

if(node == null){

return 0;

}else{

int i = height(node.getLchild());

int j = height(node.getRchild());

return (i

}

}

//得到节点的个数

public int size(TreeNode node){

if(node == null){

return 0;

}else{

return 1+ size(node.getLchild())+size(node.getRchild());

}

}

//递归实现先序遍历 NLR

public void preOrder(TreeNode node){

if(node != null){

System.out.print(node.getData() + " ");

preOrder(node.getLchild());

preOrder(node.getRchild());

}

}

//非递归实现先序遍历 NLR

public void nonRecPreOrder(TreeNode node){

Stack> nodeStack = new Stack>();

TreeNode nodeTemp = node; //nodeTemp作为遍历指针

while(nodeTemp != null || !nodeStack.isEmpty()){  //当nodeTemp非空或栈非空时循环

if(nodeTemp != null){  //根指针非空,遍历左子树

nodeStack.push(nodeTemp);  //根指针进栈

System.out.print(nodeStack.peek().getData() + " "); //根指针退栈,访问根节点

nodeTemp = nodeTemp.getLchild();  //每遇到非空二叉树先向左走

}else{ //再向右子树走

nodeTemp = nodeStack.pop();

nodeTemp = nodeTemp.getRchild();

}

}

}

//递归实现中序遍历 LNR

public void inOrder(TreeNode node){

if(node != null){

inOrder(node.getLchild());

System.out.print(node.getData() + " ");

inOrder(node.getRchild());

}

}

//非递归实现中序遍历 LNR

public void nonRecInOrder(TreeNode node){

Stack> nodeStack = new Stack>();

TreeNode nodeTemp = node;  //nodeTemp作为遍历指针

while(nodeTemp != null || !nodeStack.isEmpty()){  //当nodeTemp非空或栈非空时循环

if(nodeTemp != null){  //根指针非空,遍历左子树

nodeStack.push(nodeTemp);  //根指针进栈

nodeTemp = nodeTemp.getLchild();  //每遇到非空二叉树先向左走

}else{

nodeTemp = nodeStack.pop();  //根指针退栈,访问根节点

System.out.print(nodeTemp.getData() +" ");

nodeTemp = nodeTemp.getRchild();  //再向右子树走

}

}

}

//递归实现后序遍历 LNR

public void postOrder(TreeNode node){

if(node != null){

postOrder(node.getLchild());

postOrder(node.getRchild());

System.out.print(node.getData() + " ");

}

}

//非递归实现后序遍历 LNR

public void nonRecPostOrder(TreeNode node){

Stack> nodeStack = new Stack>();

TreeNode nodeTemp = node; //nodeTemp作为遍历指针

TreeNode preNode = null;  //表示最近一次访问的节点

while(nodeTemp != null || !nodeStack.isEmpty()){  //当nodeTemp非空或栈非空时循环

while(nodeTemp != null){  //一直向左走,遍历左子树

nodeStack.push(nodeTemp);

nodeTemp = nodeTemp.getLchild();

}

nodeTemp = nodeStack.peek();

if(nodeTemp.getRchild()==null || nodeTemp.getRchild() == preNode){  //右子树为空或右子树已被访问时,该节点出栈

nodeTemp = nodeStack.pop();

System.out.print(nodeTemp.getData()+" ");

preNode = nodeTemp;  //将该节点赋值给最近一个访问节点

nodeTemp = null;  //此处很重要,将刚出栈节点设置为空,对应于while循环的条件之一,否则陷入死循环

}else{

nodeTemp = nodeTemp.getRchild(); //遍历右子树

}

}

}

//层次遍历

public void levelOrder(TreeNode root){

Queue> nodeQueue = new LinkedList>();

TreeNode node = null;

nodeQueue.add(root);  //将根节点入队

while(!nodeQueue.isEmpty()){  //队列不空循环

node = nodeQueue.peek();

System.out.print(node.getData()+" ");

nodeQueue.poll();    //队头元素出队

if(node.getLchild() != null){    //左子树不空,则左子树入队列

nodeQueue.add(node.getLchild());

}

if(node.getRchild() != null){    //右子树不空,则右子树入队列

nodeQueue.add(node.getRchild());

}

}

}

public static void main(String args[]){

//将一个数组转化为一颗完全二叉树

Object[] array = {1,2,3,4,5,6,7,8};

BinaryTree bt = new BinaryTree();

TreeNode root = bt.buildTree(array);

System.out.print("树的高度:");

System.out.println(bt.height(root));

System.out.print("节点的个数:");

System.out.println(bt.size(root));

System.out.println("先序遍历:");

bt.preOrder(root);

System.out.println("\n"+"非递归先序遍历:");

bt.nonRecPreOrder(root);

System.out.println();

System.out.println("中序遍历:");

bt.inOrder(root);

System.out.println("\n"+"非递归中序遍历:");

bt.nonRecInOrder(root);

System.out.println();

System.out.println("后序遍历:");

bt.postOrder(root);

System.out.println("\n"+"非递归后序遍历:");

bt.nonRecPostOrder(root);

System.out.println();

System.out.println("层次遍历:");

bt.levelOrder(root);

//手工构建一颗二叉树

TreeNode nodeA = new TreeNode("A");

TreeNode nodeB = new TreeNode("B");

TreeNode nodeC = new TreeNode("C");

TreeNode nodeD = new TreeNode("D");

TreeNode nodeE = new TreeNode("E");

TreeNode nodeF = new TreeNode("F");

TreeNode nodeG = new TreeNode("G");

TreeNode nodeH = new TreeNode("H");

TreeNode nodeI = new TreeNode("I");

nodeA.setLchild(nodeB);

nodeA.setRchild(nodeD);

nodeB.setRchild(nodeC);

nodeD.setLchild(nodeE);

nodeD.setRchild(nodeF);

nodeF.setLchild(nodeG);

nodeF.setRchild(nodeI);

nodeG.setRchild(nodeH);

System.out.println("\n\n"+"*****************");

System.out.print("树的高度:");

System.out.println(bt.height(nodeA));

System.out.print("节点的个数:");

System.out.println(bt.size(nodeA));

System.out.println("先序遍历:");

bt.preOrder(nodeA);

System.out.println();

System.out.println("中序遍历:");

bt.inOrder(nodeA);

System.out.println();

System.out.println("后序遍历:");

bt.postOrder(nodeA);

System.out.println();

System.out.println("层次遍历:");

bt.levelOrder(nodeA);

}

}

上述程序的运行结果:

树的高度:4

节点的个数:8

先序遍历:

1 2 4 8 5 3 6 7

非递归先序遍历:

1 2 4 8 5 3 6 7

中序遍历:

8 4 2 5 1 6 3 7

非递归中序遍历:

8 4 2 5 1 6 3 7

后序遍历:

8 4 5 2 6 7 3 1

非递归后序遍历:

8 4 5 2 6 7 3 1

层次遍历:

1 2 3 4 5 6 7 8

*****************

树的高度:5

节点的个数:9

先序遍历:

A B C D E F G H I

中序遍历:

B C A E D G H F I

后序遍历:

C B E H G I F D A

层次遍历:

A B D C E F G I H

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值