栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

二叉树的遍历(前序遍历,中序遍历,后序遍历,层次遍历)Java实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二叉树的遍历(前序遍历,中序遍历,后序遍历,层次遍历)Java实现

1.遍历模式
前序遍历:根->左->右(深度优先)
中序遍历:左->根->右(深度优先)
后序遍历:左->右->根(深度优先)
层次遍历:每一层从左到右(广度优先)
2.例子:

3.前序遍历的实现思想和API构建:

代码实现:

//前序遍历
	
	//获取整个树中所有的键
	public Queue preTraversal(){
		Queue keys =new Queue();
		preTraversal(root,keys);
		return keys;
	}
	
	//获取指定树x的所有键,并放到key队列中
	private void preTraversal(Node x,Queue keys){
		//安全性验证
		if(x==null){
			return;
		}
		//把x节点的key放到keys中
		keys.InQueue(x.key);
		//递归遍历x节点的左子树
		if(x.left!=null){
			preTraversal(x.left,keys);
		}
		//递归遍历x节点的右子树
		if(x.right!=null){
			preTraversal(x.right,keys);
		}
	}
	

4.中序遍历的实现思想和API构建:

代码实现:

//中序遍历
	//使用中序遍历来获取树中所有的键
	public Queue midTraversal(){
		Queue keys =new Queue();
		midTraversal(root,keys);
		return keys;
	}
	
	//使用中序遍历来获取指定树x中的所有键,并存放到keys中
	private void midTraversal(Node x,Queue keys){
		//安全性校验
		if(x==null){
			return;
		}
		//先递归,把左子树中所有的键放到keys中
		if(x.left!=null){
			midTraversal(x.left,keys);
		}
		//把当前节点的键放到keys中
		keys.InQueue(x.key);
		//再递归,把右子树中的键放到keys中
		if(x.right!=null){
		midTraversal(x.right,keys);
		}
	}
	

5.后序遍历的实现思想和API构建:

代码实现:

//后序遍历
	//使用后序遍历来获取树中所有的键
	public Queue backTraversal(){
		Queue keys =new Queue();
		backTraversal(root,keys);
		return keys;
	}
	
	//使用后序遍历来获取指定树x中的所有键,并存储到keys队列中
	private void backTraversal(Node x,Queue keys){
		//安全性校验
		if(x==null){
			return;
		}
		//先递归,把左子树的键全部放到keys中
		if(x.left!=null){
			backTraversal(x.left,keys);
		}
		//再递归把右子树中的键全部放到keys中
		if(x.right!=null){
			backTraversal(x.right,keys);
		}
		//最后把x节点的键放到keys中
		keys.InQueue(x.key);
	}
	

6.层次遍历的实现思想和API构建:



代码实现:

//层次遍历
	//使用层次遍历获取整个树中所有的键
	public Queue layerTraversal(){
		//定义两个队列,分别存储树中的键和树中的节点
		Queue keys =new Queue();
		Queue nodes =new Queue();
		//默认往队列中放入根节点
		nodes.InQueue(root);
		//循环弹出节点,循环结束的条件是节点为空了,没有节点了
		while(!nodes.isEmpty()){
			//1.从队列中弹出一个节点,把key放入到keys中
			Node n=nodes.OutQueue();
			keys.InQueue(n.key);
			//2.判断当前节点还有没有左子节点,如果有,则放入到nodes中
			if(n.left!=null){
				nodes.InQueue(n.left);
			}
			//3.判断当前节点还有没有右子节点,如果有,则放入到nodes中
			if(n.right!=null){
				nodes.InQueue(n.right);
			}
		}
		return keys;
	}

程序测试结果:
源代码:

package Tree;

import Queue.Queue;

public class binaryTreeTraversalTest {
    public static void main(String[] args) {
		//创建树
    	binaryTree tree =new binaryTree();
    	tree.put("E","蜘蛛侠");
    	tree.put("B","蝙蝠侠");
    	tree.put("G","钢铁侠");
    	tree.put("A","绿巨人");
    	tree.put("D","美国队长");
    	tree.put("F","黑豹");
    	tree.put("H","战争机器");
    	tree.put("C","战争机器");
    	//前序遍历
    	//把键值全部存储到队列keys中
    	Queue keys =tree.preTraversal();
    	//根据keys的键,再去调用树中的get方法来获得value
    	System.out.print("前序遍历:");
    	for(String str:keys){
    		String value=tree.get(str);
    		System.out.print("["+str+"--"+value+"]"+"-->");
    	}
    	System.out.println("n--------------------------------------------");
    	
    	//中序遍历
    	System.out.print("中序遍历:");
    	Queue keys2 =tree.midTraversal();
    	for(String str:keys2){
    		String value=tree.get(str);
    		System.out.print("["+str+"--"+value+"]"+"-->");
    	}
    	System.out.println("n--------------------------------------------");
    	
    	//后序遍历
    	System.out.print("后序遍历:");
    	Queue keys3 =tree.backTraversal();
    	for(String str:keys3){
    		String value=tree.get(str);
    		System.out.print("["+str+"--"+value+"]"+"-->");
    	}
    	System.out.println("n--------------------------------------------");
    	
    	//层次遍历
    	System.out.print("层次遍历:");
    	Queue keys4 =tree.layerTraversal();
    	for(String str:keys4){
    		String value=tree.get(str);
    		System.out.print("["+str+"--"+value+"]"+"-->");
    	}
    	System.out.println("n--------------------------------------------");
	}
}

运行结果:

关于树的所有代码打包:

package Tree;

import Queue.Queue;

public class binaryTree,value > {
  //记录根节点
	private Node root;
	//记录元素个数
	private int N=0;
	//构造方法,初始化二叉树
	public binaryTree(key key,value value,Node left,Node right) {
		// TODO Auto-generated constructor stub
		this.root=new Node(key, value, left, right);
		this.N=1;
	}
	public binaryTree() {
		// TODO Auto-generated constructor stub
	}
	
	private class Node{
		//存储键
		public key key;
		//存储值
		public value value;
		//存储左节点
		public Node left;
		//存储右节点
		public Node right;
		//构造方法
		public Node(key key,value value,Node left,Node right) {
			// TODO Auto-generated constructor stub
			this.key=key;
			this.value=value;
			this.left=left;
			this.right=right;
		}
	}
	
	//获取元素个数
	public int size(){
		return N;
	}
	
	//向树中添加元素,key-value
	public void put(key key,value value){
		root=put(root,key,value);
	}
	
	//向指定的树x中添加key-value,并返回添加元素后新的树
	private Node put(Node x,key key,value value){
		//如果x子树为空,则把新节点当作根节点使用
		if(x==null){
			N++;//元素个数+1
			return new Node(key, value, null, null); //直接创建一个根节点并返回
		}
		int result=key.compareTo(x.key);
		//如果x子树不为空,比较key的值,比当前节点小就往左放,比当前节点大就往右放
		if(result>0){
			//递归调用put直到找到根节点右侧合适的位置
			x.right=put(x.right,key,value); 
		}else if(result<0){
			//递归调用put直到找到根节点左侧合适的位置
			x.left=put(x.left,key,value);
		}else{
			//等于当前节点就替换value即可
			x.value=value;
		}
		return x;
	}
	
	//查询树中指定的值的value
	public value get(key key){
		
		return get(root,key);
	}
	
	//从指定的树x中,查找对应键的value值
	public value get(Node x,key key){
		//子树x为null,
		if(x==null){
			return null;
		}
		//子树x不为null
		//创建result存储key值的比较结果
		int result=key.compareTo(x.key);
		//如果key值大于当前节点的key,则往右找
		if(result>0){
			return get(x.right,key);
		}
		//如果key值小于当前节点的key则往左找
		else if(result<0){
			return get(x.left,key);
		}
		//key等于当前节点的key则返回结果
		else{
			return x.value;
		}
	}
	
	//删除树中key对应的value
	public 	void delete(key key){
		delete(root,key);
	}
	
	//删除指定树中key对应的value值,并返回删除后的新树
	public Node delete(Node x,key key){
		//x树为空
		if(x==null){
			return null;
		}
		//x树不为空
		//创建result存储比较结果
		int result=key.compareTo(x.key);
		//如果result小于0则继续向左找
		if(result<0){
			x.left=delete(x.left,key);
		}
		//如果result>0则继续向右找
		else if(result>0){
			x.right=delete(x.right,key);
		}
		//如果result等于零,则找到该节点,完成删除即可
		else{
			//元素个数-1
			N--;    //一进来就是元素个数-1,避免出现bug,因为能进入到else里面来表面必定要删除一个元素
			//首先得找到一个合适的节点来替换当前要删除的节点
			//把目标节点定位右子树的最小节点
			//第一步,如果左子树或右子树为空的情况
			if(x.right==null){
				return x.left;
			}
			
			if(x.left==null){
				return x.right;
			}
			//如果左子树和右子树都不为空的话,就要遍历寻找右子树的最小节点
			//创建一个最小节点变量,默认为让它等于当前节点的右子树节点
			Node minNode=x.right;	
			//通过遍历来找到最小的节点
			//顺着右子树的左边往下找,找到右子树最左边的叶子节点即可
			while(minNode.left!=null){
				minNode=minNode.left;
			}
			//将这个最小的节点先删除掉,然后再拿去替换真正要删除的节点
			//先找到最小节点的父节点,方法是如果一个节点的左节点的左节点为空的话就是
			Node n=x.right;
			while(n.left!=null){
				if(n.left.left==null){
					n.left=null;     //删除完成
				}else{
					//变换n节点即可
					n=n.left;
				}
			}
			//真正的删除x节点
			//1.让x节点的左子树成为minNode的左子树
			minNode.left=x.left;
			//2.让x节点的右子树成为minNode的右子树
			minNode.right=x.right;
			//3.让x节点的父节点成为minNode的父节点
			x=minNode;
		}	
		return x;
	}
	
	//查找整个树中的最小键
	public key minKey(){
		return minKey(root).key;
	}
	
	//在指定树x中找到最小键所在的节点
	public Node minKey(Node x){
		//需要判断x还有没有左子树,如果有,则继续向左找,如果没有,则x就是最小键所在的节点
		if(x.left!=null){
			return minKey(x.left);
		}else{
			return x;
		}
	 }
	
	//查找整个树中的最大键
	public key maxKey(){
		return maxKey(root).key;
	}
	
	//在指定树x中找到最小键所在的节点
	public Node maxKey(Node x){
		//需要判断x还有没有右子树,如果有,则继续向右找,如果没有,则x就是最大键所在的节点
		if(x.right!=null){
			return maxKey(x.right);
		}else{
			return x;
		}
	 }
	
	
	//前序遍历
	
	//获取整个树中所有的键
	public Queue preTraversal(){
		Queue keys =new Queue();
		preTraversal(root,keys);
		return keys;
	}
	
	//获取指定树x的所有键,并放到key队列中
	private void preTraversal(Node x,Queue keys){
		//安全性验证
		if(x==null){
			return;
		}
		//把x节点的key放到keys中
		keys.InQueue(x.key);
		//递归遍历x节点的左子树
		if(x.left!=null){
			preTraversal(x.left,keys);
		}
		//递归遍历x节点的右子树
		if(x.right!=null){
			preTraversal(x.right,keys);
		}
	}
	
	//中序遍历
	//使用中序遍历来获取树中所有的键
	public Queue midTraversal(){
		Queue keys =new Queue();
		midTraversal(root,keys);
		return keys;
	}
	
	//使用中序遍历来获取指定树x中的所有键,并存放到keys中
	private void midTraversal(Node x,Queue keys){
		//安全性校验
		if(x==null){
			return;
		}
		//先递归,把左子树中所有的键放到keys中
		if(x.left!=null){
			midTraversal(x.left,keys);
		}
		//把当前节点的键放到keys中
		keys.InQueue(x.key);
		//再递归,把右子树中的键放到keys中
		if(x.right!=null){
		midTraversal(x.right,keys);
		}
	}
	
	//后序遍历
	//使用后序遍历来获取树中所有的键
	public Queue backTraversal(){
		Queue keys =new Queue();
		backTraversal(root,keys);
		return keys;
	}
	
	//使用后序遍历来获取指定树x中的所有键,并存储到keys队列中
	private void backTraversal(Node x,Queue keys){
		//安全性校验
		if(x==null){
			return;
		}
		//先递归,把左子树的键全部放到keys中
		if(x.left!=null){
			backTraversal(x.left,keys);
		}
		//再递归把右子树中的键全部放到keys中
		if(x.right!=null){
			backTraversal(x.right,keys);
		}
		//最后把x节点的键放到keys中
		keys.InQueue(x.key);
	}
	
	//层次遍历
	//使用层次遍历获取整个树中所有的键
	public Queue layerTraversal(){
		//定义两个队列,分别存储树中的键和树中的节点
		Queue keys =new Queue();
		Queue nodes =new Queue();
		//默认往队列中放入根节点
		nodes.InQueue(root);
		//循环弹出节点,循环结束的条件是节点为空了,没有节点了
		while(!nodes.isEmpty()){
			//1.从队列中弹出一个节点,把key放入到keys中
			Node n=nodes.OutQueue();
			keys.InQueue(n.key);
			//2.判断当前节点还有没有左子节点,如果有,则放入到nodes中
			if(n.left!=null){
				nodes.InQueue(n.left);
			}
			//3.判断当前节点还有没有右子节点,如果有,则放入到nodes中
			if(n.right!=null){
				nodes.InQueue(n.right);
			}
		}
		return keys;
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782427.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号