《漫画算法--小灰的算法之旅》
二叉树是典型的非线性数据结构,遍历时候需要把非线性关联的节点转换成一个线性序列,以不同的方式进行遍历,遍历出的顺序也不相同。
常用的遍历方式是:前序遍历、中序遍历、后序遍历;(个人理解所谓的前序、中序、后序指的是根节点遍历的顺序是前?是中?是后?)
package com.java.array;
public class BinaryTree {
// 前序遍历
public static void preOrderTraveral(TreeNode node) {
if (node == null) {
return;
}
System.out.println(node.data);
preOrderTraveral(node.leftChild);
preOrderTraveral(node.rightChild);
}
// 后序遍历
public static void postOrderTraveral(TreeNode node) {
if (node == null) {
return;
}
preOrderTraveral(node.leftChild);
preOrderTraveral(node.rightChild);
System.out.println(node.data);
}
// 中序遍历
public static void inOrderTraveral(TreeNode node) {
if (node == null) {
return;
}
preOrderTraveral(node.leftChild);
System.out.println(node.data);
preOrderTraveral(node.rightChild);
}
}
class TreeNode {
int data;
TreeNode leftChild;
TreeNode rightChild;
public TreeNode(int data) {
this.data = data;
}
}
上述是采用递归的方式进行遍历。
(1)栈的数据结构进行二叉树的前序遍历
/**
* 二叉树非递归的前序遍历
*
* @param root 根节点
*/
public static void preOrderTraveralWithStack(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
TreeNode treeNode = root;
while (treeNode != null || !stack.isEmpty()) {
//迭代访问节点的左孩子,并入栈
while (treeNode != null) {
System.out.println(treeNode.data);
stack.push(treeNode.leftChild);
treeNode = treeNode.leftChild;
}
// 如果节点没有左孩子,则弹出栈顶节点,访问节点右孩子
while (!stack.isEmpty()) {
treeNode = stack.pop();
treeNode = treeNode.rightChild;
}
}
}
(2)二叉树的层序遍历
/**
* 二叉树的广义遍历
*
* @param root 根节点
*/
public static void levelOrderTraversal(TreeNode root) {
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode treeNode = queue.poll();
System.out.println(treeNode);
if (treeNode.leftChild != null) {
queue.offer(treeNode.leftChild);
}
if (treeNode.rightChild != null) {
queue.offer(treeNode.rightChild);
}
}
}
Stack 源码阅读
/**
* Removes the object at the top of this stack and returns that
* object as the value of this function.
* (删除此堆栈顶部的对象,并将该对象作为此函数的值返回。)
*
* @return The object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
/**
* Looks at the object at the top of this stack without removing it
* from the stack.( 查看栈顶元素,不移除元素。)
*
* @return the object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
Queue源码阅读
/**
* Inserts the specified element into this queue if it is possible to do
* so immediately without violating capacity restrictions.
* When using a capacity-restricted queue, this method is generally
* preferable to {@link #add}, which can fail to insert an element only
* by throwing an exception.
如果可以在不违反容量限制的情况下立即将指定的元素插入此队列。使用容量受限的队列时,通常首选此方法,比add 好。
*
* @param e the element to add
* @return {@code true} if the element was added to this queue, else
* {@code false}
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null and
* this queue does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this queue
*/
boolean offer(E e);
/**
* Inserts the specified element into this queue if it is possible to do so
* immediately without violating capacity restrictions, returning
* {@code true} upon success and throwing an {@code IllegalStateException}
* if no space is currently available.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Collection#add})
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null and
* this queue does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this queue
*/
boolean add(E e);
/**
* Retrieves and removes the head of this queue,(检索并删除此队列的头)
* or returns {@code null} if this queue is empty.(或如果此队列为空,则返回{@code null})
*
* @return the head of this queue, or {@code null} if this queue is empty
*/
E poll();
/**
* Retrieves, but does not remove, the head of this queue,
* or returns {@code null} if this queue is empty.
* 检索但不删除此队列的开头,如果此队列为空,则返回{@code null}。
* @return the head of this queue, or {@code null} if this queue is empty
*/
E peek();