java 求二叉树的叶子结点,下面的代码不知道哪里出错了!
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 求二叉树的叶子结点,下面的代码不知道哪里出错了!相关的知识,希望对你有一定的参考价值。
package com.overtake;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class BintreeTest
public static void main(String[] args) throws Exception
MyTree myTree = new MyTree();
myTree.root = new BintNode();
myTree.createbintree(myTree.root);
System.out.print("当前树的前序:");
myTree.preorder(myTree.root);
// System.out.println("\n==========");
System.out.println("\n叶子结点个数为:" + myTree.num(myTree.root));
class MyTree
// BintNode bintNode;
BintNode root;
int count = 0;
void createbintree(BintNode myTree) throws Exception
String str;
// myTree = new BintNode();
System.out.println("请输入结点:");
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
str = reader.readLine();
if ("".equals(str.trim()))
myTree = null;
else
myTree.data = str;
myTree.lchild = new BintNode();
createbintree(myTree.lchild);
myTree.rchild = new BintNode();
createbintree(myTree.rchild);
public int num(BintNode root2)
if (root2 == null)
return 0;
else if (root2.lchild == null && root2.rchild == null)
return 1;
else
return (num(root2.lchild) + num(root2.rchild));
void preorder(BintNode r) // /前序
if (r != null)
if (r.lchild != null || r.rchild != null)
System.out.print(r.data + " ");
else if (r.lchild == null || r.rchild == null)
System.out.print("");
else
System.out.print(r.data);
preorder(r.lchild);
preorder(r.rchild);
class BintNode
String data;
BintNode lchild;
BintNode rchild;
createbintree方法中。以lz的讲的先输入a、再输入三回车,也就是当前只有一个节点a。下面就以楼主的数据来讲一下函数所走流程
1.可是当楼主输入a之后,按完第一个回车
当前取得的数据a,走else分支,接下来就到myTree.data = str;//为节点赋值,假设为父节点1
myTree.lchild = new BintNode();//为myTree建立了左节点
createbintree(myTree.lchild);
//递归调用跳到2
myTree.rchild = new BintNode();//创建右节点
createbintree(myTree.rchild);
//递归调用跳到3
2.输入第二个回车,数据为空,那么走if分支,myTree=null,照理说应该将myTree该节点赋值为空,也就代表没有该节点。
其实这个想法是错误的。在1中,为父节点1分配了左孩子,已经是new出来的对象。不知道lz对函数调用中的形参(也就是函数名所带的参数)的值,是怎么理解。有两种形式的
1)值传递:即使是值传递,在函数体中,改变的也只是一个临时变量的值。并不会影响到实参的值
2)引用传递:对象间的传递,而这传递只是引用关系的传递。就是将该参数指向该类,如果在函数体中设为null,也只是将形参与实际对象间的引用关系给去掉
本程序中,是属于引用传递,在createbintree将myTree=null,也只是断掉myTree与外部对象的关系而已,即父节点1的左孩子间的关系,所以父节点1的左孩子不为null
3.与2同样的解释,也可知道右孩子也不为空。
那么在调用num来计算叶子的个数时候,是不是根结点一开始进来,左右孩子都不为null,所以自然最后一个else。那么往下,lz再计算一下就知道结果为2
建议修改的话:
在createbintree方法中,if ("".equals(str.trim()))为空时,则myTree.data=null
然后在num方法中,计算个数的话,利用myTree.data==null return 0 ; myTree.lchild.data==null && myTree.rchild.data==null return 1 ; else 一样 参考技术A 你的方法是一个递归调用,你这样写要多输入很多的空白字符了,还有假如按输入的结果来看,你输入的值先是填入左子树,接下是左子树的左子树,这样下去,当你输入空字符之后,就递归回来,这时你还有输入 myTree.rchild = new BintNode();
createbintree(myTree.rchild);
这段代码的回调了。
。你输完数字之后多按几下回车它会出结果的(这中间不要输入值否则会增加要输入的回车)。这样你写二叉树有问题了(虽然是一个二叉树了,我想应该违背了你最初的意思了,即使没有违背,那你输入的方式也会很麻烦了)。追问
不才,还是不知道怎么解决
举个简单的例子:
输入一个a后再连续三个回车,就创建了一个只有根的二叉树。
输出的前序是a
但叶子结点输出是2(本来应该是1的)
刚刚我解释了一大段,不过看下面的发现自己错了.你提的问题下面解析清楚了,我就不再重复了,你可以看下面同仁的回答了.
数据结构 二叉树的简单理解和代码实现
前言:本章主要介绍二叉树的链式结构,及其前序、中序、后序遍历操作,还有 二叉树的其它基本操作包括求结点个数、求叶子结点个数、求第K层结点个数、求二叉树深度等。
文章目录
二叉树的链式结构
链式结构实现如下:
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* right;
struct BinaryTreeNode* left;
}BTNode;
二叉树的遍历方式
前序/中序/后续遍历代码实现
上面已经说到,前序遍历方式为根结点—>左子树—>右子树,我们用下图为例
前序遍历代码:
//二叉树前序遍历
void PreOrder(BTNode* root) {
if (root == NULL) {
printf("NULL ");
return;
}
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
中序遍历代码:
// 二叉树中序遍历
void InOrder(BTNode* root)
{
if (root == NULL) {
printf("NULL ");
return;
}
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
后序遍历代码如下:
// 二叉树后序遍历
void PostOrder(BTNode* root)
{
if (root == NULL) {
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
二叉树的基本操作
求二叉树结点个数
方法一:用全局遍历
1、全局
int size = 0;//这里不妨思考下能不能直接放入BinaryTreeSize函数内部进行定义
int BinaryTreeSize(BTNode* root)
{
if (root == NULL)
{
return;
}
else
{
++size;
}
BinaryTreeSize(root->left);
BinaryTreeSize(root->right);
}
方法二:局部变量
2、遍历 -- 局部变量
void BinaryTreeSize(BTNode* root, int* psize)
{
if (root == NULL)
return;
else
++(*psize);
BinaryTreeSize(root->left, psize);
BinaryTreeSize(root->right, psize);
}
方法三:
用递归的思想分治,计算二叉树的结点数量,可以认为
数量 = 1 + 左子树数量 + 右子树数量
,其中1是当前根结点数量
//3、分治,不再遍历
int BinaryTreeSize(BTNode* root)
{
return root == NULL ? 0 : 1
+ BinaryTreeSize(root->left)
+ BinaryTreeSize(root->right);
}
求二叉树叶子结点个数
按照递归思想,计算二叉树的叶子结点数量,我们可以认为
数量等于 = 0 + 左子树叶子结点数量 + 右子树叶子结点数量
,0是因为当前根结点有子树,说明根结点不是叶子结点.
//求叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
else if (root->left == NULL && root->right == NULL)
{
return 1;
}
else
{
return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}
}
求二叉树第K层结点个数
核心思路:求当前树的第k层=左子树的第k-1层+右子树的第k-1层
//求第k层节点个数
//核心思路:求当前树的第k层=左子树的第k-1层+右子树的第k-1层
int BinaryTreeLevelKSize(BTNode* root, int K)
{
if (root == NULL)
{
return 0;
}
if (K == 1)
{
return 1;
}
return BinaryTreeLevelKSize(root->left, K- 1) + BinaryTreeLevelKSize(root->right, K - 1);
}
求二叉树的深度/高度
二叉树的高度等于1 + 左右子树高度的最大值.
//二叉树的深度/高度
int BinaryTreeDepth(BTNode* root)
{
if (root == NULL)
{
return 0;
}
int leftDepth = BinaryTreeDepth(root->left);
int rightDepth = BinaryTreeDepth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
查找二叉树中值为x的结点
递归分治,先判断当前结点是否是目标,然后查找左子树,再查找右子树.
如果左右子树都没有找到,就返回
NULL
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
BTNode* retLeft = BinaryTreeFind(root->left, x);
if (retLeft)
{
return retLeft;
}
BTNode* retRight = BinaryTreeFind(root->right, x);
if (retRight)
{
return retRight;
}
return NULL;
}
二叉树源代码
数据结构的二叉树内容到此介绍结束了,感谢您的阅读!!!如果内容对你有帮助的话,记得给我三连(点赞、收藏、关注)——做个手有余香的人。
以上是关于java 求二叉树的叶子结点,下面的代码不知道哪里出错了!的主要内容,如果未能解决你的问题,请参考以下文章