二叉树模拟

接着我们就要写一个比较复杂的数据结构的,但是这个数据结构是很重要的,假如你想深入的学习算法等等.我们来模拟一下二叉树。

public class BiTree {

private BiTree leftTree;// 左子树

private BiTree rightTree;// 右子树

private Object data;// 节点数据

public final static int MAX = 40;

BiTree[] elements = new BiTree[MAX];// 层次遍历时保存各个节点

private  int front;//层次遍历时队首

private  int rear;//层次遍历时队尾

//构造函数

public BiTree(){

}

public BiTree(Object data) {

this.data = data;

}

public BiTree(Object data, BiTree lefTree, BiTree righTree){

this.data = data;

this.leftTree = lefTree;

this.rightTree = righTree;

}

//递归遍历二叉树(前序)

public void preOrder(BiTree tree) {

if (tree != null) {

visit(tree.data);//展示数据

preOrder(tree.leftTree);

preOrder(tree.rightTree);

}

}

//递归遍历二叉树(中序)

public void inOrder(BiTree tree) {

if (tree != null) {

inOrder(tree.leftTree);

//访问数据

visit(tree.data);

inOrder(tree.rightTree);

}

}

//递归遍历二叉树(后序)

public void postOrder(BiTree tree) {

if (tree != null) {

postOrder(tree.leftTree);

postOrder(tree.rightTree);

visit(tree.data);

}

}

//非递归实现遍历(前序)

public void iterativePreOrder(BiTree tree) {

//堆栈

Stack<BiTree> stack = new Stack<BiTree>();

if (tree != null) {

stack.push(tree);

while (!stack.isEmpty()) {

//先访问根

tree = stack.pop();

//访问根节点

visit(tree.data);

if (tree.rightTree != null)

stack.push(tree.rightTree);

if (tree.leftTree != null)

stack.push(tree.leftTree);

}

}

}

//中序实现二叉树遍历(非递归)

public  void  iterativeInOrder(BiTree tree){

//堆栈

Stack<BiTree> stack = new Stack<BiTree>();

while(tree!=null)//遍历所有的tree

{

while(tree!=null)//装入最左边的tree

{

if(tree.rightTree!=null)

{

stack.push(tree.rightTree);

}

stack.push(tree);

//指向左tree

tree=tree.leftTree;

}

//遍历树

tree=stack.pop();

//右树为空的时候,说明需要输出左边的树

while(!stack.empty() &&  tree.rightTree==null)

{

visit(tree.data);

tree=stack.pop();

}

//当左树遍历完成后要遍历根接点

visit(tree.data);

//然后继续遍历

if(!stack.empty())

{

tree=stack.pop();

}

else

{

tree=null;//退出循环

}

}

}

//非递归实现遍历(后续)

public   void  iterativePostOrder(BiTree tree)

{

//临时变量

BiTree  tempTree=tree;

Stack<BiTree> stack = new Stack<BiTree>();

//遍历所有的tree

while(tree!=null)

{

while(tree.leftTree!=null)

{

stack.push(tree);//装载左树

tree=tree.leftTree;

}

//当前节点无右子或右子已经输出

while(tree!=null  && (tree.rightTree==null || tree.rightTree == tempTree))

{

visit(tree.data);

tempTree = tree;// 记录上一个已输出节点

if(stack.empty())

return;

tree = stack.pop();

}

//装入根接点

stack.push(tree);

tree = tree.rightTree;

}

}

//层次遍历二叉树

public void LayerOrder(BiTree tree) {

elements[0]=tree;

front=0;

rear=1;

while (front<rear) {

try {

if (elements[front].data != null) {

//输出数据

System.out.print(elements[front].data + " ");

//装入左树

if (elements[front].leftTree != null)

{

elements[rear++] = elements[front].leftTree;

}

if (elements[front].rightTree != null)

{

elements[rear++] = elements[front].rightTree;

}

//数组向前移动

front++;

}

} catch (Exception e) {

break;

}

}

}

//求二叉树的高度

public static int height(BiTree tree) {

if (tree == null)

return 0;

else {//递归饭会树的高度

int leftTreeHeight = height(tree.leftTree);

int rightTreeHeight = height(tree.rightTree);

return leftTreeHeight > rightTreeHeight ? leftTreeHeight + 1: rightTreeHeight + 1;

}

}

// 求data所对应结点的层数,如果对象不在树中,结果返回-1;否则结果返回该对象在树中所处的层次,规定根节点为第一层

public int level(Object data) {

int leftLevel,rightLevel;

if (this == null)

return -1;

if (data == this.data)

return 1;

//计算左树

leftLevel = leftTree == null ? -1 : leftTree.level(data);

//计算左树

rightLevel = rightTree == null ? -1 : rightTree.level(data);

if (leftLevel < 0 && rightLevel < 0)

return -1;

return leftLevel > rightLevel ? leftLevel + 1 : rightLevel + 1;

}

// 求二叉树的结点总数(递归)

public static int nodes(BiTree tree) {

if (tree == null)

return 0;

else {

int left = nodes(tree.leftTree);

int right = nodes(tree.rightTree);

return left + right + 1;

}

}

// 求二叉树叶子节点的总数

public static int leaf(BiTree tree) {

if (tree == null)

return 0;

else {

int left = leaf(tree.leftTree);

int right = leaf(tree.rightTree);

if (tree.leftTree == null && tree.rightTree == null)

return (left + right)+1;//增加一个叶子节点

else

return left + right;

}

}

//求二叉树父节点个数

public static int fatherNodes(BiTree tree) {

//节点为空或者单节点

if (tree == null || (tree.leftTree == null && tree.rightTree == null))

return 0;

else {

int left = fatherNodes(tree.leftTree);

int right = fatherNodes(tree.rightTree);

return left + right + 1;

}

}

// 求只有一个孩子结点的父节点个数

public static int oneChildFather(BiTree tree) {

int left,right;

if (tree == null || (tree.rightTree == null && tree.leftTree == null))

return 0;

else {

left = oneChildFather(tree.leftTree);

right = oneChildFather(tree.rightTree);

if ((tree.leftTree != null && tree.rightTree == null)|| (tree.leftTree == null && tree.rightTree != null))

return left + right + 1;

else

return left + right;/* 加1是因为要算上根节点 */

}

}

// 求二叉树只拥有左孩子的父节点总数

public static int leftChildFather(BiTree tree) {

if (tree == null || tree.leftTree==null)

return 0;

else {

int left = leftChildFather(tree.leftTree);

int right = leftChildFather(tree.rightTree);

if ((tree.leftTree != null && tree.rightTree == null))

return left + right + 1;

else

return left + right;

}

}

// 求二叉树只拥有右孩子的结点总数

public static int rightChildFather(BiTree tree) {

if (tree == null || tree.rightTree == null)

return 0;

else {

int left = rightChildFather(tree.leftTree);

int right = rightChildFather(tree.rightTree);

if (tree.leftTree == null && tree.rightTree != null)

return left + right + 1;

else

return left + right;

}

}

// 计算有两个节点的父节点的个数

public static int doubleChildFather(BiTree tree) {

int left,right;

if (tree == null)

return 0;

else {

left = doubleChildFather(tree.leftTree);

right = doubleChildFather(tree.rightTree);

if (tree.leftTree != null && tree.rightTree != null)

return (left + right + 1);

else

return (left + right);

}

}

// 访问根节点

public void visit(Object data) {

System.out.print(data + " ");

}

// 将树中的每个节点的孩子对换位置

public void exChange() {

if (this == null)

return;

if (leftTree != null)

{

leftTree.exChange();//交换左树

}

if (rightTree != null)

{

rightTree.exChange();//交换右树

}

BiTree temp = leftTree;

leftTree = rightTree;

rightTree = temp;

}

//递归求所有结点的和

public  static int getSumByRecursion(BiTree tree){

if(tree==null){

return 0;

}

else{

int left=getSumByRecursion(tree.leftTree);

int right=getSumByRecursion(tree.rightTree);

return Integer.parseInt(tree.data.toString())+left+right;

}

}

//非递归求二叉树中所有结点的和

public static int getSumByNoRecursion(BiTree tree){

Stack<BiTree> stack = new Stack<BiTree>();

int sum=0;//求和

if(tree!=null){

stack.push(tree);

while(!stack.isEmpty()){

tree=stack.pop();

sum+=Integer.parseInt(tree.data.toString());

if(tree.leftTree!=null)

stack.push(tree.leftTree);

if(tree.rightTree!=null)

stack.push(tree.rightTree);

}

}

return sum;

}

/**

* @param args

*/

public static void main(String[] args) {

BiTree l = new BiTree(10);

BiTree m = new BiTree(9);

BiTree n = new BiTree(8);

BiTree h = new BiTree(7);

BiTree g = new BiTree(6);

BiTree e = new BiTree(5,n,l);

BiTree d = new BiTree(4,m,null);

BiTree c = new BiTree(3,g,h);

BiTree b = new BiTree(2, d, e);

BiTree tree = new BiTree(1, b, c);

System.out.println("递归前序遍历二叉树结果: ");

tree.preOrder(tree);

System.out.println();

System.out.println("非递归前序遍历二叉树结果: ");

tree.iterativePreOrder(tree);

System.out.println();

System.out.println("递归中序遍历二叉树的结果为:");

tree.inOrder(tree);

System.out.println();

System.out.println("非递归中序遍历二叉树的结果为:");

tree.iterativeInOrder(tree);

System.out.println();

System.out.println("递归后序遍历二叉树的结果为:");

tree.postOrder(tree);

System.out.println();

System.out.println("非递归后序遍历二叉树的结果为:");

tree.iterativePostOrder(tree);

System.out.println();

System.out.println("层次遍历二叉树结果: ");

tree.LayerOrder(tree);

System.out.println();

System.out.println("递归求二叉树中所有结点的和为:"+getSumByRecursion(tree));

System.out.println("非递归求二叉树中所有结点的和为:"+getSumByNoRecursion(tree));

System.out.println("二叉树中,每个节点所在的层数为:");

for (int p = 1; p <= 14; p++)

System.out.println(p + "所在的层为:" + tree.level(p));

System.out.println("二叉树的高度为:" + height(tree));

System.out.println("二叉树中节点总数为:" + nodes(tree));

System.out.println("二叉树中叶子节点总数为:" + leaf(tree));

System.out.println("二叉树中父节点总数为:" + fatherNodes(tree));

System.out.println("二叉树中只拥有一个孩子的父节点数:" + oneChildFather(tree));

System.out.println("二叉树中只拥有左孩子的父节点总数:" + leftChildFather(tree));

System.out.println("二叉树中只拥有右孩子的父节点总数:" + rightChildFather(tree));

System.out.println("二叉树中同时拥有两个孩子的父节点个数为:" + doubleChildFather(tree));

System.out.println("--------------------------------------");

tree.exChange();

System.out.println("交换每个节点的左右孩子节点后......");

System.out.println("递归前序遍历二叉树结果: ");

tree.preOrder(tree);

System.out.println();

System.out.println("非递归前序遍历二叉树结果: ");

tree.iterativePreOrder(tree);

System.out.println();

System.out.println("递归中序遍历二叉树的结果为:");

tree.inOrder(tree);

System.out.println();

System.out.println("非递归中序遍历二叉树的结果为:");

tree.iterativeInOrder(tree);

System.out.println();

System.out.println("递归后序遍历二叉树的结果为:");

tree.postOrder(tree);

System.out.println();

System.out.println("非递归后序遍历二叉树的结果为:");

tree.iterativePostOrder(tree);

System.out.println();

System.out.println("层次遍历二叉树结果: ");

tree.LayerOrder(tree);

System.out.println();

System.out.println("递归求二叉树中所有结点的和为:"+getSumByRecursion(tree));

System.out.println("非递归求二叉树中所有结点的和为:"+getSumByNoRecursion(tree));

System.out.println("二叉树中,每个节点所在的层数为:");

for (int p = 1; p <= 14; p++)

System.out.println(p + "所在的层为:" + tree.level(p));

System.out.println("二叉树的高度为:" + height(tree));

System.out.println("二叉树中节点总数为:" + nodes(tree));

System.out.println("二叉树中叶子节点总数为:" + leaf(tree));

System.out.println("二叉树中父节点总数为:" + fatherNodes(tree));

System.out.println("二叉树中只拥有一个孩子的父节点数:" + oneChildFather(tree));

System.out.println("二叉树中只拥有左孩子的父节点总数:" + leftChildFather(tree));

System.out.println("二叉树中只拥有右孩子的父节点总数:" + rightChildFather(tree));

System.out.println("二叉树中同时拥有两个孩子的父节点个数为:" + doubleChildFather(tree));

}

}

小结:大家可以来练习一下,自己写一遍 熟悉一下.

二叉树模拟

时间: 2024-10-05 11:41:29

二叉树模拟的相关文章

UVA 712(二叉树模拟)

L - S-Trees Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Appoint description:  System Crawler  (2014-04-01) Description  S-Trees  A Strange Tree (S-tree) over the variable set  is a binary tree representing a B

POJ 题目1105 S-Trees(二叉树模拟)

S-Trees Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1499   Accepted: 807 Description A Strange Tree (S-tree) over the variable set Xn = {x1,x2,...,xn} is a binary tree representing a Boolean function f:{0,1}->{0,1}. Each path of the

2014 UESTC Training for Data Structures J - 方师傅的01串

J - 方师傅的01串 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 方师傅过生日啦,于是蟹毛买了N个01串,想送给方师傅. 但是蟹毛觉得这些01串不够美,于是他想从中选出一些送给方师傅. 蟹毛对于p个01串的美值定义为: 这些01串的最长公共前缀的长度×p 所以蟹毛想从N个01串中选出一些,使得这些01串的美值最高. 请告诉蟹毛最好的美值是多少.

hdu 5444 Elven Postman

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Description Elves are very peculiar creatures. As we all know, they can live for a very long time and their magical prowess are not something to be taken lightly. Also, they live on tr

poj 1426 Find The Multiple (bfs 搜索)

Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18012   Accepted: 7297   Special Judge Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains

uva1354 天平难题 解题报告

uva1354 天平难题.主要有 回溯法,二叉树模拟. 当然,这道题也有很多剪枝,但是这个用二叉树性质模拟的数组应该过了,这样写,这道题,完全就足够了. 原题目链接:https://uva.onlinejudge.org/external/13/1354.pdf 题目大意: 就是首先给你一个房间的宽度r,之后有s个挂坠,第i个挂坠的重量是wi,设计一个尽量宽,但是不能宽过房间.的天平.当然会有好几组这样的数据. 这些天平棍的长度都为1,天平棍要么挂 挂坠,要么就继续挂木棍设挂的木棍必须要让天平平

HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)

[题目链接]:click here~~ [题目大意]: HDU 5444 题意:在最初为空的二叉树中不断的插入n个数.对于每个数,从根节点开始判断,如果当前节点为空,就插入当前节点,如果当前节点不为空,则小于当前节点的值,插入右子树,否则插入左子树. 接着q次询问,每次询问一个值在二叉树中从根节点开始的查找路径. 3 直接用二叉树模拟整个插入和询问的过程 代码: /* * Problem: HDU No.5444 * Running time: 0MS * Complier: G++ * Aut

Vijos P1114 FBI树【DFS模拟,二叉树入门】

描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种.由一个长度为2^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下: 1) T的根结点为R,其类型与串S的类型相同: 2) 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2:由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2. 现在给定一个长度为2^N的“0

10.26最后的模拟:改造二叉树

改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论起了二叉搜索树. 什么是二叉搜索树呢?二叉搜索树首先是一棵二叉树.设key[p]表示结点p上的数值.对于其中的每个结点p,若其存在左孩子lch,则key[p]>key[lch]:若其存在右孩子rch,则key[p]<key[rch]:注意,本题中的二叉搜索树应满足对于所有结点,其左子树