欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java实现二叉树的深度优先遍历和广度优先遍历算法示例

程序员文章站 2023-11-20 20:53:22
本文实例讲述了java实现二叉树的深度优先遍历和广度优先遍历算法。分享给大家供大家参考,具体如下: 1. 分析 二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先...

本文实例讲述了java实现二叉树的深度优先遍历和广度优先遍历算法。分享给大家供大家参考,具体如下:

1. 分析

二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。

深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历、中序遍历、后序遍历。具体说明如下:

先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。

中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。

后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。

广度优先遍历:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。

2. 举例说明

对下图所示的二叉排序树进行遍历,要求使用先序遍历(递归、非递归)、中序遍历(递归、非递归)、后序遍历(递归、非递归)和广度优先遍历。

Java实现二叉树的深度优先遍历和广度优先遍历算法示例

① 参考代码

package binarytreetraversetest;
import java.util.linkedlist;
import java.util.queue;
/**
 * 二叉树的深度优先遍历和广度优先遍历
 * @author fantasy
 * @version 1.0 2016/10/05 - 2016/10/07
 */
public class binarytreetraversetest {
  public static void main(string[] args) {
  binarysorttree<integer> tree = new binarysorttree<integer>();
    tree.insertnode(35);
    tree.insertnode(20);
    tree.insertnode(15);
    tree.insertnode(16);
    tree.insertnode(29);
    tree.insertnode(28);
    tree.insertnode(30);
    tree.insertnode(40);
    tree.insertnode(50);
    tree.insertnode(45);
    tree.insertnode(55);
    system.out.print("先序遍历(递归):");
    tree.preordertraverse(tree.getroot());
    system.out.println();
    system.out.print("中序遍历(递归):");
    tree.inordertraverse(tree.getroot());
    system.out.println();
    system.out.print("后序遍历(递归):");
    tree.postordertraverse(tree.getroot());
    system.out.println();
    system.out.print("先序遍历(非递归):");
    tree.preordertraversenorecursion(tree.getroot());
    system.out.println();
    system.out.print("中序遍历(非递归):");
    tree.inordertraversenorecursion(tree.getroot());
    system.out.println();
    system.out.print("后序遍历(非递归):");
    tree.postordertraversenorecursion(tree.getroot());
    system.out.println();
    system.out.print("广度优先遍历:");
    tree.breadthfirsttraverse(tree.getroot());
  }
}
/**
 * 结点
 */
class node<e extends comparable<e>> {
  e value;
  node<e> left;
  node<e> right;
  node(e value) {
    this.value = value;
    left = null;
    right = null;
  }
}
/**
 * 使用一个先序序列构建一棵二叉排序树(又称二叉查找树)
 */
class binarysorttree<e extends comparable<e>> {
  private node<e> root;
  binarysorttree() {
    root = null;
  }
  public void insertnode(e value) {
    if (root == null) {
      root = new node<e>(value);
      return;
    }
    node<e> currentnode = root;
    while (true) {
      if (value.compareto(currentnode.value) > 0) {
        if (currentnode.right == null) {
          currentnode.right = new node<e>(value);
          break;
        }
        currentnode = currentnode.right;
      } else {
        if (currentnode.left == null) {
          currentnode.left = new node<e>(value);
          break;
        }
        currentnode = currentnode.left;
      }
    }
  }
  public node<e> getroot(){
    return root;
  }
  /**
   * 先序遍历二叉树(递归)
   * @param node
   */
  public void preordertraverse(node<e> node) {
    system.out.print(node.value + " ");
    if (node.left != null)
      preordertraverse(node.left);
    if (node.right != null)
      preordertraverse(node.right);
  }
  /**
   * 中序遍历二叉树(递归)
   * @param node
   */
  public void inordertraverse(node<e> node) {
    if (node.left != null)
      inordertraverse(node.left);
    system.out.print(node.value + " ");
    if (node.right != null)
      inordertraverse(node.right);
  }
  /**
   * 后序遍历二叉树(递归)
   * @param node
   */
  public void postordertraverse(node<e> node) {
    if (node.left != null)
      postordertraverse(node.left);
    if (node.right != null)
      postordertraverse(node.right);
    system.out.print(node.value + " ");
  }
  /**
   * 先序遍历二叉树(非递归)
   * @param root
   */
  public void preordertraversenorecursion(node<e> root) {
    linkedlist<node<e>> stack = new linkedlist<node<e>>();
    node<e> currentnode = null;
    stack.push(root);
    while (!stack.isempty()) {
      currentnode = stack.pop();
      system.out.print(currentnode.value + " ");
      if (currentnode.right != null)
        stack.push(currentnode.right);
      if (currentnode.left != null)
        stack.push(currentnode.left);
    }
  }
  /**
   * 中序遍历二叉树(非递归)
   * @param root
   */
  public void inordertraversenorecursion(node<e> root) {
    linkedlist<node<e>> stack = new linkedlist<node<e>>();
    node<e> currentnode = root;
    while (currentnode != null || !stack.isempty()) {
      // 一直循环到二叉排序树最左端的叶子结点(currentnode是null)
      while (currentnode != null) {
        stack.push(currentnode);
        currentnode = currentnode.left;
      }
      currentnode = stack.pop();
      system.out.print(currentnode.value + " ");
      currentnode = currentnode.right;
    }
  }
  /**
   * 后序遍历二叉树(非递归)
   * @param root
   */
  public void postordertraversenorecursion(node<e> root) {
    linkedlist<node<e>> stack = new linkedlist<node<e>>();
    node<e> currentnode = root;
    node<e> rightnode = null;
    while (currentnode != null || !stack.isempty()) {
      // 一直循环到二叉排序树最左端的叶子结点(currentnode是null)
      while (currentnode != null) {
        stack.push(currentnode);
        currentnode = currentnode.left;
      }
      currentnode = stack.pop();
      // 当前结点没有右结点或上一个结点(已经输出的结点)是当前结点的右结点,则输出当前结点
      while (currentnode.right == null || currentnode.right == rightnode) {
        system.out.print(currentnode.value + " ");
        rightnode = currentnode;
        if (stack.isempty()) {
          return; //root以输出,则遍历结束
        }
        currentnode = stack.pop();
      }
      stack.push(currentnode); //还有右结点没有遍历
      currentnode = currentnode.right;
    }
  }
  /**
   * 广度优先遍历二叉树,又称层次遍历二叉树
   * @param node
   */
  public void breadthfirsttraverse(node<e> root) {
    queue<node<e>> queue = new linkedlist<node<e>>();
    node<e> currentnode = null;
    queue.offer(root);
    while (!queue.isempty()) {
      currentnode = queue.poll();
      system.out.print(currentnode.value + " ");
      if (currentnode.left != null)
        queue.offer(currentnode.left);
      if (currentnode.right != null)
        queue.offer(currentnode.right);
    }
  }
}

② 输出结果

先序遍历(递归):35 20 15 16 29 28 30 40 50 45 55
中序遍历(递归):15 16 20 28 29 30 35 40 45 50 55
后序遍历(递归):16 15 28 30 29 20 45 55 50 40 35
先序遍历(非递归):35 20 15 16 29 28 30 40 50 45 55
中序遍历(非递归):15 16 20 28 29 30 35 40 45 50 55
后序遍历(非递归):16 15 28 30 29 20 45 55 50 40 35
广度优先遍历:35 20 40 15 29 50 16 28 30 45 55

更多关于java算法相关内容感兴趣的读者可查看本站专题:《java数据结构与算法教程》、《java操作dom节点技巧总结》、《java文件与目录操作技巧汇总》和《java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。