二叉樹的建樹、遍歷(先序、中序、後序、層次)(遞迴和非遞迴)--Java實現
阿新 • • 發佈:2019-01-08
什麼是樹?什麼是二叉樹?
樹:除了根節點之外的所有節點都有且只有一個父節點,根節點沒有父節點;除了葉結點以外的所有節點,都有一個或多個子節點,葉結點沒有子節點。
二叉樹:是樹的一種特殊結構,在二叉樹中,每個節點最多隻能有兩個子節點。
二叉樹的遍歷方式:
1、先序遍歷(遞迴、非遞迴);
2、中序遍歷(遞迴、非遞迴);
3、後序遍歷(遞迴、非遞迴);
4、層次遍歷。
建樹、遍歷程式碼:
public class BinaryTree<E> {
private static class Node<E>{
public E value; //節點值
public Node<E> left; //左節點
public Node<E> right;//右節點
public Node(E value) {
this.value = value;
this.left = null;
this.right = null;
}
}
public static List<Node<Integer>> nodeList = null;//用於儲存二叉樹的節點
/**
* 建立陣列
* @param length
* @return
*/
public int[] createArray(int length){
int[] array = new int[length];
for (int i = 0; i < array.length; i++) {
array[i] = (int)(Math.random() * 100);
}
return array;
}
/**
* 建立二叉樹
*/
public void createBinaryTree(int nodeNum){
nodeList = new ArrayList<Node<Integer>>();
int[] array = createArray(nodeNum);
for(int i : array){
System.out.print(i + " ");
}
System.out.println();
for (int i = 0; i < array.length; i++) {
Node<Integer> temp = new Node<Integer>(array[i]);
nodeList.add(temp);
}
for (int parentIndex = 0; parentIndex < array.length/2 - 1; parentIndex++) {
//父節點
Node<Integer> parentNode = nodeList.get(parentIndex);
//左節點
parentNode.left = nodeList.get(parentIndex * 2 + 1);
//右節點
parentNode.right = nodeList.get(parentIndex * 2 + 2);
int lastParentIndex = array.length/2 - 1;
Node<Integer> lastParentNode = nodeList.get(lastParentIndex);
lastParentNode.left = nodeList.get(lastParentIndex * 2 + 1);
//總節點數為基數,最後一個父節點才有右孩子
if (array.length % 2 == 1) {
lastParentNode.right = nodeList.get(lastParentIndex * 2 + 2);
}
}
}
/**
* 二叉樹先序遍歷(遞迴)
* @param parentNode
*/
public void BinaryTreePreOrder(Node<E> parentNode){
if (parentNode == null) {
return;
}
System.out.print(parentNode.value + " ");
BinaryTreePreOrder(parentNode.left);
BinaryTreePreOrder(parentNode.right);
}
/**
* 二叉樹先序遍歷(迴圈)
* @param rootNode
*/
public void BinaryTreePreOrder_loop(Node<E> rootNode){
Stack<Node<E>> stack = new Stack<Node<E>>();
Node<E> cur = rootNode;
while(cur != null || !stack.isEmpty()){
while(cur != null){
System.out.print(cur.value + " ");
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
cur = cur.right;
}
}
/**
* 二叉樹中序遍歷(遞迴)
* @param parentNode
*/
public void BinaryTreeMidOrder(Node<E> parentNode){
if (parentNode == null) {
return;
}
BinaryTreeMidOrder(parentNode.left);
System.out.print(parentNode.value + " ");
BinaryTreeMidOrder(parentNode.right);
}
/**
* 二叉樹中序遍歷(迴圈)
* @param rootNode
*/
public void BinaryTreeMidOrder_loop(Node<E> rootNode){
Stack<Node<E>> stack = new Stack<Node<E>>();
Node<E> cur = rootNode;
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
System.out.print(cur.value + " ");
cur = cur.right;
}
}
/**
* 二叉樹後序遍歷(遞迴)
* @param parentNode
*/
public void BinaryTreePostOrder(Node<E> parentNode){
if (parentNode == null) {
return;
}
BinaryTreePostOrder(parentNode.left);
BinaryTreePostOrder(parentNode.right);
System.out.print(parentNode.value + " ");
}
/**
* 二叉樹後序遍歷(非遞迴)
* 先處理左右子樹,再處理根
* @param rootNode
*/
public void BinaryTreePostOrder_loop(Node<E> rootNode){
Stack<Node<E>> stack = new Stack<Node<E>>();
//使用map來標記已經訪問過的節點
Map<Node<E>, Boolean> nodeMap = new HashMap<Node<E>, Boolean>();
stack.push(rootNode);
while(!stack.isEmpty()){
Node<E> temp = stack.peek();
//獲取左子樹的左節點
if (temp.left != null && !nodeMap.containsKey(temp.left)) {
temp = temp.left;
while(temp != null){
stack.push(temp);
temp = temp.left;
}
continue;
}
//獲取右節點
if (temp.right != null && !nodeMap.containsKey(temp.right)) {
stack.push(temp.right);
continue;
}
Node<E> cur = stack.pop();
System.out.print(cur.value + " ");
nodeMap.put(cur, true);
}
}
/**
* 二叉樹層次遍歷
* @param rootNode
*/
public void BinaryTreeLevelOrder(Node<E> rootNode){
//使用佇列來實現遍歷
Queue<Node<E>> queue = new LinkedList<Node<E>>();
queue.add(rootNode);
while(!queue.isEmpty()){
Node<E> parentNode = queue.poll();
System.out.print(parentNode.value + " ");
if (parentNode.left != null) {
queue.add(parentNode.left);
}
if (parentNode.right != null) {
queue.add(parentNode.right);
}
}
}
public static void main(String[] args) {
BinaryTree<Integer> tree = new BinaryTree<Integer>();
System.out.println("遍歷前陣列:");
tree.createBinaryTree(11);
Node<Integer> rootNode = nodeList.get(0);
System.out.println("先序遍歷(遞迴):");
tree.BinaryTreePreOrder(rootNode);
System.out.println();
System.out.println("先序遍歷(非遞迴):");
tree.BinaryTreePreOrder_loop(rootNode);
System.out.println();
System.out.println("中序遍歷(遞迴):");
tree.BinaryTreeMidOrder(rootNode);
System.out.println();
System.out.println("中序遍歷(非遞迴):");
tree.BinaryTreeMidOrder_loop(rootNode);
System.out.println();
System.out.println("後序遍歷(遞迴):");
tree.BinaryTreePostOrder(rootNode);
System.out.println();
System.out.println("後序遍歷(非遞迴):");
tree.BinaryTreePostOrder_loop(rootNode);
System.out.println();
System.out.println("層次遍歷:");
tree.BinaryTreeLevelOrder(rootNode);
}
}
測試結果:
遍歷前陣列:
39 21 69 6 78 21 83 53 69 52 85
先序遍歷(遞迴):
39 21 6 53 69 78 52 85 69 21 83
先序遍歷(非遞迴):
39 21 6 53 69 78 52 85 69 21 83
中序遍歷(遞迴):
53 6 69 21 52 78 85 39 21 69 83
中序遍歷(非遞迴):
53 6 69 21 52 78 85 39 21 69 83
後序遍歷(遞迴):
53 69 6 52 85 78 21 21 83 69 39
後序遍歷(非遞迴):
53 69 6 52 85 78 21 21 83 69 39
層次遍歷:
39 21 69 6 78 21 83 53 69 52 85