二叉樹的遍歷方式有多種碑幅,前序遍歷,中序遍歷塞绿,后序遍歷沟涨,層序遍歷,在這里來介紹一下前异吻、中裹赴、后序遍歷。
- 前序遍歷:根左右
- 中序遍歷:左根右
- 后序遍歷:左右根
二叉樹
前序遍歷:ABDECF
中序遍歷:DBEACF
后序遍歷:DEBFCA
介紹一種常見題型:已知任意兩種遍歷诀浪,求出另一種遍歷棋返,前提是必須得知道中序遍歷。
方法就是通過前序或后序得到根節(jié)點(diǎn)雷猪,在中序遍歷中根據(jù)根節(jié)點(diǎn)找出左右子樹(如上睛竣,根據(jù)中序遍歷,A兩側(cè)便是左右子樹DBE求摇,CF)射沟,之后運(yùn)用遞歸的思想,便可以畫出一整棵二叉樹与境,再來求第三種遍歷就很輕松了验夯。
接下來我們用Java來簡(jiǎn)單實(shí)現(xiàn)一下二叉樹的三種遍歷方式:
有兩種實(shí)現(xiàn)方式,分別是:
- 遞歸實(shí)現(xiàn)
- 利用棧的進(jìn)出實(shí)現(xiàn)
public class BinaryTree {
private TreeNode root = null;
public BinaryTree(){
root = new TreeNode(1,"A");
}
/*
* 二叉樹
* A
* B C
* D E F
*
* */
// 創(chuàng)建如上所示二叉樹
public void createBinaryTree(){
TreeNode nodeB = new TreeNode(2, "B");
TreeNode nodeC = new TreeNode(3, "C");
TreeNode nodeD = new TreeNode(4, "D");
TreeNode nodeE = new TreeNode(5, "E");
TreeNode nodeF = new TreeNode(6, "F");
root.leftnode = nodeB;
root.rightnode = nodeC;
nodeB.leftnode = nodeD;
nodeB.rightnode = nodeE;
nodeC.rightnode = nodeF;
}
// 獲取二叉樹高度,返回私有的getHeight
public int getHeight(){
return getHeight(root);
}
// 獲取二叉樹節(jié)點(diǎn)數(shù),返回私有的getSize
public int getSize(){
return getSize(root);
}
private int getSize(TreeNode node) {
if(node == null){
return 0;
}else{
return getSize(node.leftnode) + getSize(node.rightnode) + 1;
}
}
private int getHeight(TreeNode node) {
if(node == null){
return 0;
}else{
int j = getHeight(node.leftnode);
int k = getHeight(node.rightnode);
return (j<k)?k+1:j+1;
}
}
// 前序遍歷--迭代
public void prevOrder(TreeNode node) {
if(node == null){
return;
}else {
System.out.println(node.getData());
if(node.leftnode != null) prevOrder(node.leftnode);
if(node.rightnode != null) prevOrder(node.rightnode);
}
}
// 中序遍歷--迭代
public void midOrder(TreeNode node) {
if(node == null){
return;
}else {
if(node.leftnode != null) midOrder(node.leftnode);
System.out.println(node.getData());
if(node.rightnode != null) midOrder(node.rightnode);
}
}
// 后序遍歷--迭代
public void postOrder(TreeNode node) {
if(node == null){
return;
}else {
if(node.leftnode != null) postOrder(node.leftnode);
if(node.rightnode != null) postOrder(node.rightnode);
System.out.println(node.getData());
}
}
// 前序遍歷--棧
public void nonprevOrder(TreeNode node){
if(node == null){
return;
}
Stack<TreeNode> st = new Stack<>();
st.push(node);
while(!st.isEmpty()){
TreeNode p = st.pop();
System.out.println(p.getData());
if(p.rightnode != null) st.push(p.rightnode);
if(p.leftnode != null) st.push(p.leftnode);
}
}
// 中序遍歷--棧
public void nonmidOrder(TreeNode node){
if(node == null){
return;
}
Stack<TreeNode> st = new Stack<>();
TreeNode n = node;
while(!st.isEmpty() || n != null){
if(n != null){
st.push(n);
n = n.leftnode;
}else{
n = st.pop();
System.out.println(n.getData());
n = n.rightnode;
}
}
}
// 后序遍歷--棧
public void nonpostOrder(TreeNode node){
if (node == null){
return;
}
Stack<TreeNode> st = new Stack<>();
// 創(chuàng)建另一個(gè)棧摔刁,來存儲(chǔ)從st棧中拋出的元素
Stack<TreeNode> output = new Stack<>();
TreeNode n = node;
while (!st.isEmpty() || n != null){
if (n != null){
output.push(n);
st.push(n);
n = n.rightnode;
}else {
n = st.pop();
n = n.leftnode;
}
}
while (output.size() >0){
System.out.println(output.pop().getData());
}
}
// 內(nèi)部類簿姨,二叉樹的節(jié)點(diǎn)
public class TreeNode<T>{
private int index;
private T data;
private TreeNode<T> leftnode;
private TreeNode<T> rightnode;
// 構(gòu)造函數(shù),一個(gè)節(jié)點(diǎn)出生不知道其兒子節(jié)點(diǎn),所以為null
public TreeNode(int index, T data){
this.index = index;
this.data = data;
this.leftnode = null;
this.rightnode = null;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
public static void main (String[] args){
BinaryTree bt = new BinaryTree();
bt.createBinaryTree();
System.out.println("高度:" + bt.getHeight());
System.out.println("節(jié)點(diǎn)個(gè)數(shù):" + bt.getSize());
System.out.println("--前序--");
bt.prevOrder(bt.root);
System.out.println("--中序--");
bt.midOrder(bt.root);
System.out.println("--后序--");
bt.postOrder(bt.root);
System.out.println("--前序--");
bt.nonprevOrder(bt.root);
System.out.println("--中序--");
bt.nonmidOrder(bt.root);
System.out.println("--后序--");
bt.nonpostOrder(bt.root);
}
}