二叉树遍历思路
1、前序遍历:
a.先输出当前结点(初始时的时候是root节点)
b.如果左子结点不为空,则递归继续前序遍历
c.如果右子结点不为空,则递归继续前序遍历
如图遍历顺序为:12345
2、中序遍历:
a.如果左子结点不为空,则递归继续中序遍历
b.输出当前结点
c.如果右子结点不为空,则递归继续中序遍历
如图遍历顺序为:21435
3、后序遍历:
a.如果左子结点不为空,则递归继续后序遍历
b.如果右子结点不为空,则递归继续后序遍历
c.输出当前结点
如图遍历顺序为:24531
创建二叉树的数据结构
class HeroNode01{
public int no;
public String name;
public HeroNode01 left; //左节点默认为Null
public HeroNode01 right; //右节点 默认为null
public HeroNode01(int no, String name) {
this.no = no;
this.name = name;
}
public HeroNode01() {
}
@Override
public String toString() {
return "HeroNode01{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode01 getLeft() {
return left;
}
public void setLeft(HeroNode01 left) {
this.left = left;
}
public HeroNode01 getRight() {
return right;
}
public void setRight(HeroNode01 right) {
this.right = right;
}
//先序遍历
public void preOrder(){
//输出父节点
System.out.println(this);
//递归访问左子树
if(this.left!=null){
this.left.preOrder();
}
//递归访问右子树
if (this.right!=null){
this.right.preOrder();
}
}
//中序遍历
public void infixOrder(){
//递归访问左子树
if(this.left!=null){
this.left.infixOrder();
}
//输出父节点
System.out.println(this);
//递归访问右子树
if (this.right!=null){
this.right.infixOrder();
}
}
//后序遍历
public void postOrder(){
//递归访问左子树
if(this.left!=null){
this.left.postOrder();
}
//递归访问右子树
if (this.right!=null){
this.right.postOrder();
}
//输出父结点
System.out.println(this);
}
}
创建根结点数据结构
class BinaryTreeRoot{
private HeroNode01 root;
public void setRoot(HeroNode01 root) {
this.root = root;
}
//先序遍历
public void preOrder(){
if(this.root!=null){
this.root.preOrder();
}else {
System.out.println("二叉树为空,无法访问!");
}
}
//中序遍历
public void infixOrder(){
if(this.root!=null){
this.root.infixOrder();
}else {
System.out.println("二叉树为空,无法访问!");
}
}
//后序遍历
public void postOrder(){
if(this.root!=null){
this.root.postOrder();
}else {
System.out.println("二叉树为空,无法访问!");
}
}
}
手动创建一棵二叉树
//首先创建一颗二叉树
BinaryTreeRoot binaryTreeRoot=new BinaryTreeRoot();
//创建需要的节点
HeroNode01 root=new HeroNode01(1,"宋江");
HeroNode01 node2=new HeroNode01(2,"吴用");
HeroNode01 node3=new HeroNode01(3,"卢俊义");
HeroNode01 node4=new HeroNode01(4,"林冲");
HeroNode01 node5=new HeroNode01(5,"关胜");
root.setLeft(node2);
root.setRight(node3);
node3.setLeft(node4);
node3.setRight(node5);
binaryTreeRoot.setRoot(root);
//测试
System.out.println("前序遍历");
binaryTreeRoot.preOrder();
//测试
System.out.println("中序遍历");
binaryTreeRoot.infixOrder();
//测试
System.out.println("后序遍历");
binaryTreeRoot.postOrder();
二叉树-查找指定结点
思路分析:
前序查找思路:
1、先判断当前节点的no是否等于要查找的
2、如果是相等,则返回当前节点
3、如果不等,则判断当前节点的左子树是否为空,如果不为空,则
递归前序查找。
4、如果左递归前序查找找到该节点,则返回,否则继续判断,当前
结点的右子结点是否为空,如果不空,则继续右递归前序查找。
中序查找思路:
1、判断当前节点的左子树节点是否为空,如果不为空,则递归中序
查找。
2、如果找到,则返回,如果没有找到,就和当前结点比较,如果是
则返回当前结点,否则继续右递归中序查找
3、如果右递归中序查找,找到就返回,否则返回Null
后序查找思路:
1、判断当前节点的左子树是否为空,如果不为空,则递归后序查找
2、如果找到,就返回,如果没有找到,就判断当前结点的右子节点
是否为空,则右递归进行后序查找,如果找到,就返回。
3、就和当前节点进行,比如,如果是则返回,否则返回null
前序查找
//前序查找
public HeroNode01 preOrderSearch(int no) {
System.out.println("进入前序查找:");
//比较是不是当前结点
if(this.no==no){
return this;
}
//1.则判断当前结点的左子节点是否为空,如果不为空,则递归前序查找
//2、如果左递归前序查找,找到结点,则返回
HeroNode01 heroNode01=null;
//递归访问左子树
if(this.left!=null){
heroNode01 = this.left.preOrderSearch(no);
}
if(heroNode01!=null){
return heroNode01;
}
//1、左递归前序查找,找到该结点,则返回
//2、当前结点的右子结点是否为空,如果不空则继续向右递归前序查找
if (this.right!=null){
heroNode01 = this.right.preOrderSearch(no);
}
return heroNode01;
}
中序查找
//中序查找
public HeroNode01 infixOrderSearch(int no) {
System.out.println("进入中序查找:");
HeroNode01 heroNode01=null;
//1、判断当前节点的左子树节点是否为空,如果不为空,则递归中序
if(this.left!=null){
heroNode01=this.left.infixOrderSearch(no);
}
//如果找到则直接返回,不用再继续向右查找
if(heroNode01!=null){
return heroNode01;
}
//如果找到则返回该结点
if(this.no==no){
return this;
}
//1、没有找到且右子树不为空则继续向右查找,
//2、如果右递归中序查找,找到就返回,否则返回Null
if(this.right!=null){
heroNode01 = this.right.infixOrderSearch(no);
}
return heroNode01;
}
后序查找
//后序查找
public HeroNode01 postOrderSearch(int no) {
System.out.println("进入后序查找:");
HeroNode01 heroNode01=null;
//1、先判断当前结点的左子树是否为空,如果不为空,则递归后序查找
if(this.left!=null){
heroNode01 = this.left.postOrderSearch(no);
}
//2、如果左子树找到则返回
if(heroNode01!=null){
return heroNode01;
}
//3、否则则判断右子树是否为空不为空则继续向右递归查找
if(this.right!=null){
heroNode01=this.right.postOrderSearch(no);
}
//如果右子树找到则返回
if(heroNode01!=null){
return heroNode01;
}
//如果左右节点,都没有找到再来判断该结点
if(this.no==no){
return this;
}
return heroNode01;
}
删除结点
规定:
1)如果删除的结点是叶子结点,则删除该结点
2)如果删除的是非叶子结点,则删除该子树
思路:
首先:
考虑如果树是空树root,如果只有一个root结点,则等价将二叉树置空
然后:
1、由于我们的二叉树是单向的,所以我们是判断当前节点的子节点是否是
需要删除的结点。
2、如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将
this.left=null;并且就返回(结束递归删除)
3、如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将
this.right=null;并且就返回(结束递归删除)
4、如果第2步和第3步没有删除结点,那么我们就需要向左子树进行递归
删除。
5、如果第4步也没有删除结点,则应该向右子树进行递归删除。
public void delNode(int no){
//2、如果当前结点的左子结点不为空,并且左子结点
// 就是要删除结点,就将this.left=null;并且就返回(结束递归删除)
if(this.left!=null && this.left.no==no){
this.left=null;
return;
}
//3、如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将
// his.right=null;并且就返回(结束递归删除)
if(this.right!=null && this.right.no==no){
this.right=null;
return;
}
//向左递归删除
if(this.left!=null){
this.left.delNode(no);
}
//向右递归删除
if(this.right!=null){
this.right.delNode(no);
}
}
顺序存储二叉树
从数据存储来看,数据存储方式和树的存储方式可以相互转换,即数组可以转换为树,树也可以转换为数组,如图所示:
顺序二叉树的特点:
1、顺序二叉树通常只考虑完全二叉树
2、第n个元素的左子结点为 2*n+1
3、第n个元素的右子结点为2*n+2
4、第n个元素的父结点为(n-1)/2
5、n表示二叉树中的第几个元素(按0开始编号如图所示:)
下面实现如图所示数组到树之间的转换,给出中序遍历和前序遍历两种方式。实现思想主要根据顺序二叉树的特点进行实现。
class ArrBinaryTree01{
private int[] arr; //存储数据结点的数组
public ArrBinaryTree01() {
}
public ArrBinaryTree01(int[] arr) {
this.arr = arr;
}
//重装preOrder
public void preOrder(){
this.preOrder(0);
}
//编写一个方法,完成顺序存储二叉树的前序遍历
/**
* 前序遍历
* @param index 数组下标
*/
public void preOrder(int index){
//如果数组为空,或者arr.length=0
if(arr==null || arr.length==0){
System.out.println("数组为空,不能按照二叉树的前序遍历");
}
//输出当前这个元素
System.out.println(arr[index]);
//向左递归遍历
if(index*2+1<arr.length){
preOrder(index*2+1);
}
//向右递归遍历
if(index*2+2<arr.length){
preOrder(index*2+2);
}
}
//重装infixOrder
public void infixOrder(){
this.infixOrder(0);
}
/**
* 中序遍历
* @param index 数组下标
*/
public void infixOrder(int index){
//如果数组为空,或者arr.length=0
if(arr==null || arr.length==0){
System.out.println("数组为空,不能按照二叉树的前序遍历");
}
//向左递归遍历
if(index*2+1<arr.length){
preOrder(index*2+1);
}
//输出当前这个元素
System.out.println(arr[index]);
//向右递归遍历
if(index*2+2<arr.length){
preOrder(index*2+2);
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。