二叉树T:一个有穷的结点集合。
这个集合可以为空
若不为空,则它是由根结点和称为其左子树TL和右子树TR的
两个不相交的二叉树组成。
特殊的二叉树
斜二叉树
完美二叉树
完全二叉树
二叉树性质:
一个二叉树第 i 层的最大结点数为?
深度为k的二叉树有最大结点总数为?
对任何非空二叉树 T,若n0表示叶结点的个数、n2是度为2的非叶结点个数,那么两者满足关系n0= n2+1。
遍历核心问题:二维结构的线性化
从结点访问其左、右儿子结点,访问左儿子后,右儿子结点怎么办?
解决方案:需要一个存储结构保存暂时不访问的结点
存储结构:堆栈、队列
表达式树:
先序遍历->前缀表达式
中序遍历->中缀表达式 (会受到运算符优先级的影响)
后序遍历->后缀表达式
层序遍历
要想通过两种遍历序列确定二叉树:“中序定根,先后定左右”
前序遍历序列 和 中缀遍历序列
中缀遍历序列 和 后缀遍历序列
如何使用先序和中序序列来确定一棵二叉树
根据先序遍历序列第一个节点确定根节点
根据根节点在中序遍历序列中分割出左右两个子序列
对左子树和右子树分别递归使用相同的方法继续分解
package 二叉树.链表存储实现遍历;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.IconifyAction;
class TreeNode{
private int element;
private TreeNode leftNode;
private TreeNode rightNode;
public TreeNode(int element) {
this.element=element;
}
public TreeNode() {
}
public TreeNode(int element, TreeNode leftNode, TreeNode rightNode) {
super();
this.element = element;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
public int getElement() {
return element;
}
public void setElement(int element) {
this.element = element;
}
public TreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(TreeNode leftNode) {
this.leftNode = leftNode;
}
public TreeNode getRightNode() {
return rightNode;
}
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
}
package 二叉树.链表存储实现遍历;
import javax.management.Query;
import org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID;
import 工具.堆栈.链式存储实现.Node;
import 工具.堆栈.链式存储实现.Stack;
import 工具.队列.顺序存储结构.Queue;
public class BinaryTree {
private TreeNode root;
public BinaryTree(TreeNode treeNode) {
root=treeNode;
}
public BinaryTree() {
root=null;
}
//先序遍历(递归)
public void preOrderTraversal1(TreeNode treeNode) {
System.out.print(treeNode.getElement()+" ");
if(treeNode.getLeftNode()!=null) {
preOrderTraversal1(treeNode.getLeftNode());
}
if(treeNode.getRightNode()!=null) {
preOrderTraversal1(treeNode.getRightNode());
}
}
//先序遍历(非递归,父节点入栈)
public void preOrderTraversal2(TreeNode treeNode) {
Stack stack=new Stack();
while(treeNode!=null||!stack.isEmyty()) {
while(treeNode!=null) {
stack.push(treeNode);
System.out.print(treeNode.getElement()+" ");
treeNode=treeNode.getLeftNode();
}
treeNode=(TreeNode) stack.pop();
if(treeNode.getRightNode()!=null) {
treeNode=treeNode.getRightNode();
}else {
treeNode=null;
}
}
}
//先序遍历(非递归,右节点进栈)
public void preOrderTraversal3(TreeNode treeNode) {
Stack stack=new Stack();
while(treeNode!=null) {
while(treeNode!=null) {
System.out.print(treeNode.getElement()+" ");
if(treeNode.getRightNode()!=null) {
stack.push(treeNode.getRightNode());
}
treeNode=treeNode.getLeftNode();
}
treeNode=(TreeNode)stack.pop();
}
}
//中序遍历(递归)
public void inOrderTraversal1(TreeNode treeNode) {
if(treeNode.getLeftNode()!=null) {
inOrderTraversal1(treeNode.getLeftNode());
}
System.out.print(treeNode.getElement()+" ");
if(treeNode.getRightNode()!=null) {
inOrderTraversal1(treeNode.getRightNode());
}
}
//中序遍历(迭代)
public void inOrderTraversal2(TreeNode treeNode) {
Stack stack=new Stack();
while(treeNode!=null||!stack.isEmyty()) {
while(treeNode!=null) {
stack.push(treeNode);
treeNode=treeNode.getLeftNode();
}
treeNode=(TreeNode) stack.pop();
System.out.print(treeNode.getElement()+" ");
if(treeNode.getRightNode()!=null) {
treeNode=treeNode.getRightNode();
}else {
treeNode=null;
}
}
}
//中序遍历(非递归,右节点进栈)
public void inOrderTraversal3(TreeNode treeNode) {
Stack stack=new Stack();
while(treeNode!=null||!stack.isEmyty()) {
while(treeNode!=null) {
stack.push(treeNode);
treeNode=treeNode.getLeftNode();
}
treeNode=(TreeNode)stack.pop();
System.out.print(treeNode.getElement()+" ");
treeNode=treeNode.getRightNode();
// if(treeNode.getRightNode()!=null) {
// treeNode=treeNode.getRightNode();
// }else {
// treeNode=null;
// }
}
}
//后序遍历(递归)
public void postOrderTraversal1(TreeNode treeNode) {
if(treeNode.getLeftNode()!=null) {
postOrderTraversal1(treeNode.getLeftNode());
}
if(treeNode.getRightNode()!=null) {
postOrderTraversal1(treeNode.getRightNode());
}
System.out.print(treeNode.getElement()+" ");
}
//后序遍历(迭代)
public void postOrderTraversal2(TreeNode treeNode) {
Stack stack=new Stack();
while(treeNode!=null||!stack.isEmyty()) {
while(treeNode!=null) {
stack.push(treeNode);
treeNode=treeNode.getLeftNode();
}
Node node=stack.top();
treeNode=(TreeNode) node.getItem();
if(treeNode.getRightNode()!=null) {
if(!node.isFirst) {
treeNode=(TreeNode)stack.pop();
System.out.print(treeNode.getElement()+" ");
treeNode=null;
}else {
node.isFirst=false;
treeNode=treeNode.getRightNode();
}
}else {
treeNode=(TreeNode)stack.pop();
System.out.print(treeNode.getElement()+" ");
treeNode=null;
}
}
}
//层序遍历
public void levelOrderTraversal(TreeNode treeNode) {
Queue queue=new Queue();
queue.add(treeNode);
while (!queue.isEmpty()) {
treeNode=(TreeNode)queue.delete();
System.out.print(treeNode.getElement()+" ");
if(treeNode.getLeftNode()!=null) {
queue.add(treeNode.getLeftNode());
}
if(treeNode.getRightNode()!=null) {
queue.add(treeNode.getRightNode());
}
}
}
//输出所有叶子节点(在遍历的基础上加上非空判断)
public void showAllLeaves(TreeNode treeNode) {
if(treeNode.getLeftNode()!=null) {
showAllLeaves(treeNode.getLeftNode());
}
if(treeNode.getRightNode()!=null) {
showAllLeaves(treeNode.getRightNode());
}
if(treeNode.getLeftNode()==null&&treeNode.getRightNode()==null) {
System.out.print(treeNode.getElement()+" ");
}
}
//求二叉树的高度
public int getTreeHeight(TreeNode treeNode) {
if(treeNode==null) {
return 0;
}
int heightLeft=getTreeHeight(treeNode.getLeftNode());
int heightRight=getTreeHeight(treeNode.getRightNode());
int height=Math.max(heightLeft, heightRight)+1;
return height;
}
}