java代碼實現二叉樹的遍歷


版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/qq_33275597/article/details/52759223
一、二叉樹的定義:

二叉樹是樹形結構的一個重要類型。許多實際問題抽象出來的數據結構往往是二叉樹的形式,即使是一般的樹也能簡單地轉換為二叉樹,而且二叉樹的存儲結構及其算法都較為簡單,因此二叉樹顯得特別重要。
    二叉樹(BinaryTree)是n(n≥0)個結點的有限集,它或者是空集(n=0),或者由一個根結點及兩棵互不相交的、分別稱作這個根的左子樹和右子樹的二叉樹組成。
    這個定義是遞歸的。由於左、右子樹也是二叉樹, 因此子樹也可為空樹。下圖中展現了五種不同基本形態的二叉樹。

 

其中 (a) 為空樹, (b) 為僅有一個結點的二叉樹, (c) 是僅有左子樹而右子樹為空的二叉樹, (d) 是僅有右子樹而左子樹為空的二叉樹, (e) 是左、右子樹均非空的二叉樹。這里應特別注意的是,二叉樹的左子樹和右子樹是嚴格區分並且不能隨意顛倒的,圖 (c) 與圖 (d) 就是兩棵不同的二叉樹。


二、二叉樹的遍歷:
對於二叉樹來講最主要、最基本的運算是遍歷。
    遍歷二叉樹 是指以一定的次序訪問二叉樹中的每個結點。所謂 訪問結點 是指對結點進行各種操作的簡稱。例如,查詢結點數據域的內容,或輸出它的值,或找出結點位置,或是執行對結點的其他操作。遍歷二叉樹的過程實質是把二叉樹的結點進行線性排列的過程。假設遍歷二叉樹時訪問結點的操作就是輸出結點數據域的值,那么遍歷的結果得到一個線性序列。

常見的遍歷方法:

1、先序遍歷法:先訪問根節點,再遍歷左子樹,最后遍歷右子樹;

2、中序遍歷法:先遍歷左子樹,再訪問根節點,最后遍歷右子樹;

3、后序遍歷法:先遍歷左子樹,再遍歷右子樹,最后訪問根節點。

三、話不多說,上代碼。

public class BinaryTree {

/**
* BinaryTree 的節點數據結構
*/
private class TreeNode{
private int key = 0;
private String data = null;
private boolean isVisited = false;
private TreeNode leftChild = null;
private TreeNode rightChild = null;

public TreeNode(){}
public TreeNode(int key,String data){
this.key = key;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}

//獲取根節點
public TreeNode getRoot() {
return root;
}

public void setRoot(TreeNode root) {
this.root = root;
}


//定義根節點
private TreeNode root = null;
public BinaryTree(){
root = new TreeNode(1,"A");
}

/**
* 創建一棵二叉樹
*/
public void createBinaryTree(TreeNode root){
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.leftChild = nodeB;
root.rightChild = nodeC;
nodeB.leftChild = nodeD;
nodeB.rightChild = nodeE;
nodeC.rightChild = nodeF;

}

/**
* 前序遍歷
*/
public void preOrder(TreeNode node){
if(node != null){
visited(node);
preOrder(node.leftChild);
preOrder(node.rightChild);
}
}
/**
* 中序遍歷
* @param node
*/

public void inOrder(TreeNode node){
if(node != null){
preOrder(node.leftChild);
visited(node);
preOrder(node.rightChild);
}
}
/**
* 后序遍歷
* @param node
*/

public void postOrder(TreeNode node){
if(node != null){
preOrder(node.leftChild);
preOrder(node.rightChild);
visited(node);
}
}
/**
* 非遞歸前序遍歷
* @param node
*/

public void nonRecPreOrder(TreeNode node){
Stack<TreeNode> stack = new Stack<>();
TreeNode pNode = node;
while(pNode != null || stack.size()>0){
while(pNode != null){
visited(pNode);
stack.push(pNode);
pNode = pNode.leftChild;
}
if(stack.size()>0){
pNode = stack.pop();
pNode = pNode.rightChild;
}
}
}
/**
* 非遞歸中序遍歷
* @param node
*/

public void nonRecInOrder(TreeNode node){
Stack<TreeNode> stack = new Stack<>();
TreeNode pNode = node;
while(pNode != null || stack.size()>0){
while(pNode != null){
stack.push(pNode);
pNode = pNode.leftChild;
}
if(stack.size()>0){
pNode = stack.pop();
visited(pNode);
pNode = pNode.rightChild;
}
}
}

/**
* 非遞歸后序遍歷
* @param pNode
*/
public void nonRecPostOrder(TreeNode pNode){
Stack<TreeNode> stack = new Stack<>();
TreeNode node = pNode;
while(pNode != null){
//左子樹入棧
while(pNode.leftChild != null){
stack.push(pNode);
pNode = pNode.leftChild;
}
//當前節點無右子樹或者右子樹已輸出
while(pNode != null && (pNode.rightChild == null || pNode.rightChild == node)){
visited(pNode);
//記錄上一個已輸出的節點
node = pNode;
if(!stack.isEmpty()){
pNode = stack.pop();
}else{
return;
}
}
//右子樹入棧
stack.push(pNode);
pNode = pNode.rightChild;
}
}

private void visited(TreeNode node) {
node.isVisited = true;
System.out.println(node.data+","+node.key);
}

/**
* 計算樹的高度
*/
private int height(TreeNode node){
if(node == null){
return 0;
}else{
int i = height(node.leftChild);
int j = height(node.rightChild);
return (i<j)?j+1:i+1;
}
}

/**
* 計算樹的節點數
* @param node
* @return 樹的節點數
*/

private int size(TreeNode node){
if(node == null){
return 0;
}else{
return 1+size(node.leftChild)+size(node.rightChild);
}
}



public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
TreeNode root = binaryTree.root;
binaryTree.createBinaryTree(root);
System.out.println(binaryTree.height(root));
System.out.println(binaryTree.size(root));
binaryTree.preOrder(root);
System.out.println("*******");
binaryTree.nonRecPreOrder(root);
System.out.println("*******");
binaryTree.nonRecInOrder(root);
System.out.println("-------------");
binaryTree.nonRecPostOrder(root);
}

}
輸出結果:
3
6
A,1
B,2
D,4
E,5
C,3
F,6
*******
A,1
B,2
D,4
E,5
C,3
F,6
*******
D,4
B,2
E,5
A,1
C,3
F,6
-------------
D,4
E,5
B,2
F,6
C,3
A,1

 

————————————————
版權聲明:本文為CSDN博主「專注移動開發技術」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_33275597/article/details/52759223


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM