Java数据结构之树 (查找,删除,顺序存储与线索化二叉树)


前言

书接上文 , 本篇将介绍树结构中的查找 , 删除 , 顺序存储和线索化


提示:以下是本篇文章正文内容,下面案例可供参考

一、查找(前中后序)

1.前序遍历查找

思路 : 我们需要先判断当前结点是不是要查找的结点,如果是,则直接返回该结点,如果不是,需要分别递归左子树和右子树,知道遍历完成

	//前序遍历搜索
	public HeroNode preOrderSearch(int no) {
    
    
		
		//定义一个结果结点
		HeroNode resNode = null;
		
		//因为是前序 , 我们上来就要判断当前结点是否为我们要找的结点
		if(no == this.no) {
    
    
			return this;
		}
		
		//如果不是,且左子结点不为空,我们继续递归左子树
		if(this.left != null) {
    
    
			resNode = this.left.preOrderSearch(no);
		}
		
		if(resNode != null) {
    
    
			//说明向左遍历找到了
			return resNode;
		}
		
		//没找到,继续向右遍历
		if(this.right != null) {
    
    
			resNode = this.right.preOrderSearch(no);
		}
		
		return resNode;
	}

2.中序遍历查找

思路 : 根据中序遍历的特点,我们能很容易的得出遍历方法:
先遍历左子树 , 再判断根结点的值域是否为我们需要的,最后遍历右子树

	//中序遍历
	public HeroNode infixOrderSearch(int no) {
    
    
		//定义一个结果结点
		HeroNode resNode = null;
		
		//先递归左子树
		if(this.left != null) {
    
    
			resNode = this.left.infixOrderSearch(no);
		}
		
		if(resNode != null) {
    
    
			//说明向左遍历找到了
			return resNode;
		}
		
		//如果中序遍历没找到就和当前结点比较
		if(this.no == no) {
    
    
			return this;
		}
		
		if(this.right != null) {
    
    
			resNode = this.right.infixOrderSearch(no);
		}
		
		return resNode;
	}

3.后序遍历查找

思路类似,略

二、删除

1.思路

我们不是判断当前结点是否是要删除的结点,而是去看它的左/右子节点是否是需要删除的结点

(1).判断当前结点的左子节点是否为要删除的结点,如果是就删除,不是就递归

(2).判断当前结点的右子节点是否为要删除的结点,如果是就删除,不是就递归

(3).在树中调用删除方法时时 , 还需要判断根节点是否为空,如果不是才能去调用删除方法

2.代码

代码如下(示例):

结点类中的二叉树删除方法
public void delNode(int no) {
    
    
		//1.判断当前结点的左子节点是否为要删除的结点,如果是就删除,不是就递归
		if( this.left != null && this.left.no == no) {
    
    
			this.left = null;
		}else if(this.left != null){
    
     //只满足右结点不为空
			this.left.delNode(no);
		}
		
		//2.判断当前结点的右子节点是否为要删除的结点,如果是就删除,不是就递归
		if( this.right != null && this.right.no == no) {
    
    
			this.right = null;
		}else if(this.right != null){
    
     //只满足右结点不为空
			this.right.delNode(no);
		}
	}
	二叉树类中的调用代码
	//删除结点
	public void delNode(int no) {
    
    
		
		if(root != null) {
    
     //判空
			
			if(root.getNo() == no) {
    
     
				System.out.println(root.getName());
			}else {
    
    
				root.delNode(no); //递归
			} 
			
		}else {
    
    
			System.out.println("这是空树");
		}
		
	}

三、顺序存储二叉树

1.基本概念

顺序存储二叉树实质上就是将二叉树通过一个数组存储 , 但是遍历则是按照二叉树的方式进行遍历的 , 父子结点和前驱后继关系,是通过下面的公式来实现的

第n个元素的左子结点 : 2n+1
右子节点 : 2n+2
父节点 : (n-1/2) 向下取整

顺序存储结构通常只考虑完全二叉树,这里也讲讲啥是完全二叉树

1.叶子结点只出现在层次最大的两层
2.若右分支最大层数为L层 ,左分支最大层数为L 或 L+1层

在这里插入图片描述

2.代码实现

	前序遍历实现顺序存储
	
class ArrBinaryTree{
    
    
	private int[] arr; //存储数据结点

	public ArrBinaryTree(int[] arr) {
    
    
		this.arr = arr; //构造函数,向顺序存储二叉树中传入一个数组
	}
	public void preOrder() {
    
     
		this.preOrder(0);
	}
	
	
	//前序遍历 [公式] : n2+1 , 2n+2 , (n-1)/2
	public void preOrder(int index) {
    
    
		//判空
		if(arr == null || arr.length ==0) {
    
    
			System.out.println("树为空");
			return;
		}
		//输出当前元素
		System.out.println(arr[index]);
		//左递归
		if( (index*2+1) < arr.length ) {
    
    
			this.preOrder(2 * index + 1); //左递归
		}
		//右递归
		if( (index*2+2) < arr.length ) {
    
    
			this.preOrder(2 * index + 2);
		}
	}
}

3.如何优雅地调用前序遍历

public void preOrder() {
    
     
		this.preOrder(0);
	}

上面这段代码实际上是对下面void preOrder(int index) 方法的重载 , 原因是 ,在主函数调用void preOrder(int index)方法时,我们需要传入一个参数0, 这样方法才能正常启动.

但是 ,传一个0参数非常的不优雅 ,因此我们对它进行一个重载, 重载的无参函数再去调用有参函数,这样就避免的参数外露

四、线索化二叉树

虚线为线索化后的指针,如果在左边引出表示指向前驱结点,右边表示后继结点

在这里插入图片描述
按中序遍历得到的结果为 : 5,2,6,1,8,3

注意 : 图文无关!

这里是中序线索化的核心代码

public void threadedNode(HeroNode node){
    
    
        //判空
        if(node == null){
    
    
            return ;
        }
        //线索化左子树
        threadedNode(node.getLeft());
        
        //线索化当前结点
        if(node.getLeft() == null){
    
    
            node.setLeft(pre); //设置左子节点
            node.setLeftType(1); //指向前驱
        }
        
        if(pre != null && node.getRight() == null){
    
    
            node.setRight(pre); //
            node.setRightType(1); //指向后继
        }
        
        pre = node; //相当于指针后退
        
        //线索化右子树
        threadedNode(node.getRight());

    }    

猜你喜欢

转载自blog.csdn.net/qq_45596525/article/details/109403506