java二叉树的基本算法_java 数据结构与算法---二叉树

本文介绍了二叉树的基本概念,包括满二叉树和完全二叉树的特性,并详细阐述了如何在Java中实现二叉排序树,包括插入节点、查找节点以及三种遍历方式(前序、中序、后序)。通过实例展示了二叉树的操作方法。
摘要由CSDN通过智能技术生成

原理来自百度百科 推荐数据演示网址 :https://www.cs.usfca.edu/~galles/visualization/BST.html

一、什么是二叉树

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的(i-1)次方个结点;深度为k的二叉树至多有2的k次方然后减1个结点(次方不会敲所以用文字描述);对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。

dbe33084-59d6-4cd8-a7fd-8c36e285295d.png

二、二叉树的分类:

1、满二叉树:除叶子结点外的所有结点均有两个子结点。

67710afd-11f1-44a2-ba17-739555d7e669.png

满二叉树的性质:

一颗树深度为h,最大层数为k,深度与最大层数相同,k=h;

树的第k层,则该层的叶子节点个数为2k;

第k层的结点个数是2的(k-1)次方。

总结点个数是2的k次方减1,且总节点个数一定是奇数。

2、完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~(h-1)层) 的结点数都达到最大个数,第h层所有的结点都连续集中在最左边,这就是完全二叉树。

4e4f5f14-26b1-43b6-8813-f3847477fcd6.png

完全二叉树的特点是:

1)只允许最后一层有空缺结点且空缺在右边,即叶子结点只能在层次最大的两层上出现;

2)对任一结点,如果其右子树的深度为j,则其左子树的深度必为j或j+1。 即度为1的点只有1个或0个。

满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。

三、二叉树在数据结构中的实现

二叉树在一般数据结构中是按照二叉排序树进行实现、使用的。二叉排序树(Binary Sort Tree):又称二叉查找树(Binary Search Tree),亦称二叉搜索树。

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

8d4cddaa-31c2-4e83-9794-1321c330ad0c.png

1、二叉排序树节点的数据结构

private static class Node{

private E e;//当前节点的数据

private Node leftNode;//当前节点左子节点

private Node rightNode;//当前节点右子节点

public Node(E e, Node leftNode, Node rightNode) {

super();

this.e = e;

this.leftNode = leftNode;

this.rightNode = rightNode;

}

}

2、插入节点

如果是空树(不存在节点),则直接插入。

如果不是空树,则从根节点开始查找相应的节点,即查找新节点的父节点,当父节点找到后,根据新节点的值来确定新节点是在左节点上,还是右节点上。

public void insert(E e) {

Node node=new Node(e,null,null);

if(root==null) {

root=node;

}else {

Node fNode=root;

Node parentNode=root;//要找的父节点

while(true) {

parentNode=fNode;

if(compareToE(e,fNode.e)) {

fNode=fNode.leftNode;

if(fNode==null) {

parentNode.leftNode=node;

break;

}

}else {

fNode=fNode.rightNode;

if(fNode==null) {

parentNode.rightNode=node;

break;

}

}

}

}

size++;

}

//只是实现了数值比较

private boolean compareToE(E a,E b) {

Integer a1=(Integer) a;

Integer b1=(Integer) b;

return a1

}

3、查找节点

从根节点开始查找,如果要查找的节点值比父节点值小,则查左子节点,否则查右子节点,直到查到为止,如果不存在就返回null

public Node find(E e){

if(root.e==e) {

return root;

}

Node fNode=root;

while(true) {

if(compareToE(e,fNode.e)) {

fNode=fNode.leftNode;

}else {

if(fNode.e.equals(e)) {

return fNode;

}

fNode=fNode.rightNode;

}

if(fNode==null) {

return null;

}

}

}

4、二叉树的遍历方式

6e71b372-edbf-4cf9-8ce4-ab24a60ef42d.png

A、先序遍历 遍历规则 访问节点,访问该节点的左子树,访问该节点的右子树 23 ->20 ->24 (每一个节点都是该规则)

public void preTraversalTree(Node node) {

if(node!=null) {

node.display();

preTraversalTree(node.leftNode);

preTraversalTree(node.rightNode);

}

}

结果: E:23 E:20 E:19 E:21 E:22 E:24 E:23 E:25 E:30

B、中序遍历: 遍历规则 先遍历左子树,然后该节点,最后遍历该节点右子树 20 ->23 ->24 (每一个节点都是该规则)

public void cenTraversalTree(Node node) {

if(node!=null) {

cenTraversalTree(node.leftNode);

node.display();

cenTraversalTree(node.rightNode);

}

}

结果: E:19 E:20 E:21 E:22 E:23 E:23 E:24 E:25 E:30

C、后续遍历 遍历规则 先遍历左子树,然会遍历该节点右子树,最后该节点, 20 ->24 ->23 (每一个节点都是该规则)

public void aftTraversalTree(Node node) {

if(node!=null) {

aftTraversalTree(node.leftNode);

aftTraversalTree(node.rightNode);

node.display();

}

}

结果: E:19 E:22 E:21 E:20 E:23 E:30 E:25 E:24 E:23

完整代码

3d1ea0e4-93c4-41de-a90f-172091ab270f.gif

dd75a502-a8ac-45d7-b30b-d11f0b872de0.gif

package com.jalja.org.algorithm;

public class MyTree {

private Node root;//根节点

private int size=0;//树中节点的个数

public MyTree() {

}

private static class Node{

private E e;//当前节点的数据

private Node leftNode;//当前节点左子节点

private Node rightNode;//当前节点右子节点

public Node(E e, Node leftNode, Node rightNode) {

super();

this.e = e;

this.leftNode = leftNode;

this.rightNode = rightNode;

}

public void display() {

System.out.print(" E:"+e);

}

}

//如果是空树(不存在节点),则直接插入。

//如果不是空树,则从根节点开始查找相应的节点,即查找新节点的父节点,当父节点找到后,根据新节点的值来确定新节点是在左节点上,还是右节点上。

public void insert(E e) {

Node node=new Node(e,null,null);

if(root==null) {

root=node;

}else {

Node fNode=root;

Node parentNode=root;//要找的父节点

while(true) {

parentNode=fNode;

if(compareToE(e,fNode.e)) {

fNode=fNode.leftNode;

if(fNode==null) {

parentNode.leftNode=node;

break;

}

}else {

fNode=fNode.rightNode;

if(fNode==null) {

parentNode.rightNode=node;

break;

}

}

}

}

size++;

}

//只是实现了数值比较

private boolean compareToE(E a,E b) {

Integer a1=(Integer) a;

Integer b1=(Integer) b;

return a1

}

//从根节点开始查找,如果要查找的节点值比父节点值小,则查左子节点,否则查右子节点,直到查到为止,如果不存在就返回null

public Node find(E e){

if(root.e==e) {

return root;

}

Node fNode=root;

while(true) {

if(compareToE(e,fNode.e)) {

fNode=fNode.leftNode;

}else {

if(fNode.e.equals(e)) {

return fNode;

}

fNode=fNode.rightNode;

}

if(fNode==null) {

return null;

}

}

}

public void preTraversalTree(Node node) {

if(node!=null) {

node.display();

preTraversalTree(node.leftNode);

preTraversalTree(node.rightNode);

}

}

public void cenTraversalTree(Node node) {

if(node!=null) {

cenTraversalTree(node.leftNode);

node.display();

cenTraversalTree(node.rightNode);

}

}

public void aftTraversalTree(Node node) {

if(node!=null) {

aftTraversalTree(node.leftNode);

aftTraversalTree(node.rightNode);

node.display();

}

}

public static void main(String[] args) {

MyTree myTree=new MyTree();

myTree.insert(23);

myTree.insert(20);

myTree.insert(24);

myTree.insert(19);

myTree.insert(21);

myTree.insert(23);

myTree.insert(25);

myTree.insert(22);

myTree.insert(30);

myTree.aftTraversalTree(myTree.find(23));

}

}

View Code

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值