總結深度優先與廣度優先的區別

一、區別html

       1) 二叉樹的深度優先遍歷的非遞歸的通用作法是採用棧,廣度優先遍歷的非遞歸的通用作法是採用隊列。java

       2) 深度優先遍歷:對每個可能的分支路徑深刻到不能再深刻爲止,並且每一個結點只能訪問一次。要特別注意的是,二叉樹的深度優先遍歷比較特殊,能夠細分爲先序遍歷、中序遍歷、後序遍歷。具體說明以下:node

  • 先序遍歷:對任一子樹,先訪問根,而後遍歷其左子樹,最後遍歷其右子樹。
  • 中序遍歷:對任一子樹,先遍歷其左子樹,而後訪問根,最後遍歷其右子樹。
  • 後序遍歷:對任一子樹,先遍歷其左子樹,而後遍歷其右子樹,最後訪問根。

        廣度優先遍歷:又叫層次遍歷,從上往下對每一層依次訪問,在每一層中,從左往右(也能夠從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點能夠訪問爲止。   算法

     3)深度優先搜素算法:不所有保留結點,佔用空間少;有回溯操做(即有入棧、出棧操做),運行速度慢。數據庫

          廣度優先搜索算法:保留所有結點,佔用空間大; 無回溯操做(即無入棧、出棧操做),運行速度快。post

          一般 深度優先搜索法不所有保留結點,擴展完的結點從數據庫中彈出刪去,這樣,通常在數據庫中存儲的結點數就是深度值,所以它佔用空間較少。this

因此,當搜索樹的結點較多,用其它方法易產生內存溢出時,深度優先搜索不失爲一種有效的求解方法。  url

          廣度優先搜索算法,通常需存儲產生的全部結點,佔用的存儲空間要比深度優先搜索大得多,所以,程序設計中,必須考慮溢出和節省內存空間的問題。spa

但廣度優先搜索法通常無回溯操做,即入棧和出棧的操做,因此運行速度比深度優先搜索要快些設計

2.二叉樹的遍歷

先序遍歷(遞歸):35 20 15 16 29 28 30 40 50 45 55 
中序遍歷(遞歸):15 16 20 28 29 30 35 40 45 50 55 
後序遍歷(遞歸):16 15 28 30 29 20 45 55 50 40 35 
先序遍歷(非遞歸):35 20 15 16 29 28 30 40 50 45 55 
中序遍歷(非遞歸):15 16 20 28 29 30 35 40 45 50 55 
後序遍歷(非遞歸):16 15 28 30 29 20 45 55 50 40 35 
廣度優先遍歷:35 20 40 15 29 50 16 28 30 45 55

代碼:

package BinaryTreeTraverseTest;  
  
import java.util.LinkedList;  
import java.util.Queue;  
  
/** 
 * 二叉樹的深度優先遍歷和廣度優先遍歷 
 * @author Fantasy 
 * @version 1.0 2016/10/05 - 2016/10/07 
 */  
public class BinaryTreeTraverseTest {  
    public static void main(String[] args) {  
          
    BinarySortTree<Integer> tree = new BinarySortTree<Integer>();  
          
        tree.insertNode(35);  
        tree.insertNode(20);  
        tree.insertNode(15);  
        tree.insertNode(16);  
        tree.insertNode(29);  
        tree.insertNode(28);  
        tree.insertNode(30);  
        tree.insertNode(40);  
        tree.insertNode(50);  
        tree.insertNode(45);  
        tree.insertNode(55);  
          
        System.out.print("先序遍歷(遞歸):");  
        tree.preOrderTraverse(tree.getRoot());  
        System.out.println();  
        System.out.print("中序遍歷(遞歸):");  
        tree.inOrderTraverse(tree.getRoot());  
        System.out.println();  
        System.out.print("後序遍歷(遞歸):");  
        tree.postOrderTraverse(tree.getRoot());  
        System.out.println();  
          
        System.out.print("先序遍歷(非遞歸):");  
        tree.preOrderTraverseNoRecursion(tree.getRoot());  
        System.out.println();  
        System.out.print("中序遍歷(非遞歸):");  
        tree.inOrderTraverseNoRecursion(tree.getRoot());  
        System.out.println();  
        System.out.print("後序遍歷(非遞歸):");  
        tree.postOrderTraverseNoRecursion(tree.getRoot());  
        System.out.println();  
          
        System.out.print("廣度優先遍歷:");  
        tree.breadthFirstTraverse(tree.getRoot());  
    }  
}  
  
/** 
 * 結點 
 */  
class Node<E extends Comparable<E>> {  
      
    E value;  
    Node<E> left;  
    Node<E> right;  
      
    Node(E value) {  
        this.value = value;  
        left = null;  
        right = null;  
    }  
      
}  
  
/** 
 * 使用一個先序序列構建一棵二叉排序樹(又稱二叉查找樹) 
 */  
class BinarySortTree<E extends Comparable<E>> {  
      
    private Node<E> root;  
      
    BinarySortTree() {  
        root = null;  
    }  
      
    public void insertNode(E value) {     
        if (root == null) {  
            root = new Node<E>(value);  
            return;  
        }      
        Node<E> currentNode = root;  
        while (true) {  
            if (value.compareTo(currentNode.value) > 0) {  
                if (currentNode.right == null) {  
                    currentNode.right = new Node<E>(value);  
                    break;  
                }  
                currentNode = currentNode.right;  
            } else {  
                if (currentNode.left == null) {  
                    currentNode.left = new Node<E>(value);  
                    break;  
                }  
                currentNode = currentNode.left;  
            }  
        }  
    }  
      
    public Node<E> getRoot(){  
        return root;  
    }  
  
    /** 
     * 先序遍歷二叉樹(遞歸) 
     * @param node 
     */  
    public void preOrderTraverse(Node<E> node) {  
        System.out.print(node.value + " ");  
        if (node.left != null)  
            preOrderTraverse(node.left);  
        if (node.right != null)  
            preOrderTraverse(node.right);  
    }  
      
    /** 
     * 中序遍歷二叉樹(遞歸) 
     * @param node 
     */  
    public void inOrderTraverse(Node<E> node) {  
        if (node.left != null)  
            inOrderTraverse(node.left);  
        System.out.print(node.value + " ");  
        if (node.right != null)  
            inOrderTraverse(node.right);  
    }  
      
    /** 
     * 後序遍歷二叉樹(遞歸) 
     * @param node 
     */  
    public void postOrderTraverse(Node<E> node) {  
        if (node.left != null)  
            postOrderTraverse(node.left);  
        if (node.right != null)  
            postOrderTraverse(node.right);  
        System.out.print(node.value + " ");  
    }  
      
    /** 
     * 先序遍歷二叉樹(非遞歸) 
     * @param root 
     */  
    public void preOrderTraverseNoRecursion(Node<E> root) {  
        LinkedList<Node<E>> stack = new LinkedList<Node<E>>();  
        Node<E> currentNode = null;  
        stack.push(root);  
        while (!stack.isEmpty()) {  
            currentNode = stack.pop();  
            System.out.print(currentNode.value + " ");  
            if (currentNode.right != null)  
                stack.push(currentNode.right);  
            if (currentNode.left != null)  
                stack.push(currentNode.left);  
        }  
    }  
      
    /** 
     * 中序遍歷二叉樹(非遞歸) 
     * @param root 
     */  
    public void inOrderTraverseNoRecursion(Node<E> root) {  
        LinkedList<Node<E>> stack = new LinkedList<Node<E>>();  
        Node<E> currentNode = root;  
        while (currentNode != null || !stack.isEmpty()) {  
            // 一直循環到二叉排序樹最左端的葉子結點(currentNode是null)  
            while (currentNode != null) {  
                stack.push(currentNode);  
                currentNode = currentNode.left;  
            }  
            currentNode = stack.pop();  
            System.out.print(currentNode.value + " ");  
            currentNode = currentNode.right;  
        }     
    }  
      
    /** 
     * 後序遍歷二叉樹(非遞歸) 
     * @param root 
     */  
    public void postOrderTraverseNoRecursion(Node<E> root) {  
        LinkedList<Node<E>> stack = new LinkedList<Node<E>>();  
        Node<E> currentNode = root;  
        Node<E> rightNode = null;  
        while (currentNode != null || !stack.isEmpty()) {  
            // 一直循環到二叉排序樹最左端的葉子結點(currentNode是null)  
            while (currentNode != null) {  
                stack.push(currentNode);  
                currentNode = currentNode.left;  
            }  
            currentNode = stack.pop();  
            // 當前結點沒有右結點或上一個結點(已經輸出的結點)是當前結點的右結點,則輸出當前結點  
            while (currentNode.right == null || currentNode.right == rightNode) {  
                System.out.print(currentNode.value + " ");  
                rightNode = currentNode;  
                if (stack.isEmpty()) {  
                    return; //root以輸出,則遍歷結束  
                }  
                currentNode = stack.pop();  
            }  
            stack.push(currentNode); //還有右結點沒有遍歷  
            currentNode = currentNode.right;  
        }  
    }  
      
    /** 
     * 廣度優先遍歷二叉樹,又稱層次遍歷二叉樹 
     * @param node 
     */  
    public void breadthFirstTraverse(Node<E> root) {  
        Queue<Node<E>> queue = new LinkedList<Node<E>>();  
        Node<E> currentNode = null;  
        queue.offer(root);  
        while (!queue.isEmpty()) {  
            currentNode = queue.poll();  
            System.out.print(currentNode.value + " ");  
            if (currentNode.left != null)  
                queue.offer(currentNode.left);  
            if (currentNode.right != null)  
                queue.offer(currentNode.right);  
        }  
    }  
      
}  

3.圖

 圖的遍歷之 深度優先搜索和廣度優先搜索

相關文章
相關標籤/搜索