java二叉树详解_二叉树详解

树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。本篇博客将详细为大家解析二叉树。

首先介绍两个概念:

满二叉树:在一棵二叉树中,如果所有分支结点都有左孩子和右孩子结点,并且叶子结点都集中在二叉树的最下层,这样的树叫做满二叉树

如:

8bcefadf94d38193c543d94037bdae03.png

完全二叉树:若二叉树中最多只有最下面两层的结点的度数可以小于2,并且最下面一层的叶子结点都是依次排列在该层最左边的位置上,则称为完全二叉树

如:

432449242e8986cf3fa7279440fb1793.png

区别:满二叉树是完全二叉树的特例,因为满二叉树已经满了,而完全并不代表满。所以形态你也应该想象出来了吧,满指的是出了叶子节点外每个节点都有两个孩子,而完全的含义则是最后一层没有满,并没有满。

二叉树的链式存储结构是一类重要的数据结构,定义结果为:

Cpp代码  37dd403745eee7994441b46b8d701900.png

//定义树的结构

struct node

{

node * lchild;

node * rchild;

string data;

//初始化

node()

{

lchild=rchild=NULL;

}

};

二叉树的建立

首先我们用户输入生成一棵二叉树,要生的的二叉树如下图所示:

#代表空结点。

ba85f8608e2bbff542b6c53ee14af017.png

下面我们根据上面图中所示的二叉树,利用先序依次输入ABDG###E#H##C#F##(即先序遍历)

生成二叉树的代码如下:

Cpp代码  37dd403745eee7994441b46b8d701900.png

//二叉树生成--先序遍历输入要生成的二叉树数据,#代表空结点

void CreateTree(node * & root)

{

char data;

cin>>data;

if(data!='#')

{

root=new node;

root->data=data;

CreateTree(root->lchild);

CreateTree(root->rchild);

}

}

二叉树节点查找

采用递归的方法在二叉树root里查找只为aim的结点,若找到此节点则返回其指针,否则返回NULL

查找代码如下:

Cpp代码  37dd403745eee7994441b46b8d701900.png

//检查二叉树是否包含数据aim,有则返回其指针

node * Findnode(node * & root,string aim)

{

node * p;

if(root==NULL)//空树

return NULL;

else if(root->data==aim)

return root;

else

{

p=Findnode(root->lchild,aim);

if(p!=NULL)

return p;

else

return Findnode(root->rchild,aim);

}

}

这里解释一下递归中的return的意思:

return 对当前函数来说是结束了,对调用它的父函数来说你这个函数执行完成了,父函数就会接着执行下一语句。

没想到父函数马上又遇到一个return,父函数结束了,对爷爷函数来说父函数执行完成了,爷爷函数就接着执行下一个语句

二叉树遍历

1.先序遍历

先序遍历过程是:

1)访问根结点

2)先序遍历左子树

3)先序遍历右子树

先序遍历代码为:

Cpp代码  37dd403745eee7994441b46b8d701900.png

void  PreOrder(node * root)//先序遍历

{

if(root!=NULL)

{

cout<data;

PreOrder(root->lchild);

PreOrder(root->rchild);

}

}

2.中序遍历

中序遍历过程是:1)中序遍历左子树

2)访问根结点

3)中序遍历右子树

中序遍历的代码:

Cpp代码  37dd403745eee7994441b46b8d701900.png

void  InOrder(node * root)//中序遍历

{

if(root!=NULL)

{

InOrder(root->lchild);

cout<data;

InOrder(root->rchild);

}

}

3.后续遍历后序遍历过程是:

1)后序遍历左子树

2)后序遍历右子树3)访问根结点

后序遍历代码为:

Cpp代码  37dd403745eee7994441b46b8d701900.png

void  PostOrder(node * root)//后序遍历

{

if(root!=NULL)

{

PostOrder(root->lchild);

PostOrder(root->rchild);

cout<data;

}

}

二叉树高度计算

递归解法:

(1)如果二叉树为空,二叉树的深度为0

(2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1

代码如下:

Cpp代码  37dd403745eee7994441b46b8d701900.png

int NodeHeight(node * root)//计算二叉树高度

{

int lchild,rchlid;

if(root==NULL)

return 0;

else

{

lchild=NodeHeight(root->lchild);

rchlid=NodeHeight(root->rchild);

return (lchild>rchlid)?(lchild+1):(rchlid+1);

}

}

输出二叉树叶子节点

递归解法:

参考代码如下:

Cpp代码  37dd403745eee7994441b46b8d701900.png

void Showleaf(node * root)

{

if(root!=NULL)

{

if(root->lchild==NULL&&root->rchild==NULL)

cout<data;

Showleaf(root->lchild);//输出左子树叶子节点

Showleaf(root->rchild);//输出右子树叶子节点

}

}

运行结果为:

bcc358ba1f17f3fdce85129730982e2b.png

递归分析

上面源代码中,大量运用了递归算法,

下面我们来分析其中一个递归的过程。

二叉树结构为:

15e542b93000168bd03ed76754869f08.png

利用先序遍历,即代码为:

Cpp代码  37dd403745eee7994441b46b8d701900.png

void  PreOrder(node * root)//先序遍历

{

if(root!=NULL)

{

cout<data;

PreOrder(root->lchild);

PreOrder(root->rchild);

}

}

画出其运行状态图:

15eeb8ae41cecddf6b2b8b9c42d7f0f2.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值