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

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

代码实现:
//前序遍历
//获取整个树中所有的键
public Queue<key> preTraversal(){
Queue<key> keys =new Queue<key>();
preTraversal(root,keys);
return keys;
}
//获取指定树x的所有键,并放到key队列中
private void preTraversal(Node x,Queue<key> 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<key> midTraversal(){
Queue<key> keys =new Queue<key>();
midTraversal(root,keys);
return keys;
}
//使用中序遍历来获取指定树x中的所有键,并存放到keys中
private void midTraversal(Node x,Queue<key> 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<key> backTraversal(){
Queue<key> keys =new Queue<key>();
backTraversal(root,keys);
return keys;
}
//使用后序遍历来获取指定树x中的所有键,并存储到keys队列中
private void backTraversal(Node x,Queue<key> 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<key> layerTraversal(){
//定义两个队列,分别存储树中的键和树中的节点
Queue<key> keys =new Queue<key>();
Queue<Node> nodes =new Queue<Node>();
//默认往队列中放入根节点
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<String, String> tree =new binaryTree<String, String>();
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<String> 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<String> 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<String> 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<String> 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<key extends Comparable<key>,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<key> preTraversal(){
Queue<key> keys =new Queue<key>();
preTraversal(root,keys);
return keys;
}
//获取指定树x的所有键,并放到key队列中
private void preTraversal(Node x,Queue<key> 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<key> midTraversal(){
Queue<key> keys =new Queue<key>();
midTraversal(root,keys);
return keys;
}
//使用中序遍历来获取指定树x中的所有键,并存放到keys中
private void midTraversal(Node x,Queue<key> 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<key> backTraversal(){
Queue<key> keys =new Queue<key>();
backTraversal(root,keys);
return keys;
}
//使用后序遍历来获取指定树x中的所有键,并存储到keys队列中
private void backTraversal(Node x,Queue<key> 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<key> layerTraversal(){
//定义两个队列,分别存储树中的键和树中的节点
Queue<key> keys =new Queue<key>();
Queue<Node> nodes =new Queue<Node>();
//默认往队列中放入根节点
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;
}
}

本文详细介绍了二叉树的四种遍历方式——前序遍历、中序遍历、后序遍历和层次遍历,并分别提供了Java代码实现及程序测试结果,帮助理解深度优先和广度优先的遍历策略。
Java实现&spm=1001.2101.3001.5002&articleId=123751128&d=1&t=3&u=21e8cce725844156a52f1c0e929ffaf5)
4206

被折叠的 条评论
为什么被折叠?



