数据结构与算法——二叉树的深度优先和广度优先

前期准备知识html

二叉树基本知识:数据结构与算法——数据结构知识概括node

 

1、广度优先算法

又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也能够从右往左)访问结点,访问完一层就进入下一层,直到没有结点能够访问为止。
遍历规则:算法

  1. 先访问完当前顶点的全部邻接点。
  2. 先访问顶点的邻接点先于后访问顶点的邻接点被访问。

遍历结果:数据结构

root->A->B->C->D->Epost

程序实现:.net

/*二叉树结构*/
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
/*广度优先*/
void breadthFirstSearch(TreeNode* root){
    queue<TreeNode*> nodeQueue;  //使用队列
    nodeQueue.push(root);
    TreeNode* node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
        printf(format, node->val);
        if(node->left){
            nodeQueue.push(node->left);  //先将左子树入队
        }
        if(node->right){
            nodeQueue.push(node->right);  //再将右子树入队
        }
    }
}

 

2、深度优先算法

对每个可能的分支路径深刻到不能再深刻为止,并且每一个结点只能访问一次。要特别注意的是,二叉树的深度能够细分为先序遍历、中序遍历、后序遍历。code

遍历规则orm

不断地沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。htm

  • 先序遍历:对任一子树,先访问根,而后遍历其左子树,最后遍历其右子树。
  • 中序遍历:对任一子树,先遍历其左子树,而后访问根,最后遍历其右子树。
  • 后序遍历:对任一子树,先遍历其左子树,而后遍历其右子树,最后访问根。

遍历结果:blog

  • 先序:root->A->C->D->B->E

  • 中序:C->A->D->root->B->E

  • 后序:C->D->A->E->B->root

程序实现:

/*二叉树结构*/
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

(1)先序遍历

/*递归*/
void preOrderTraverse(TreeNode*root) {  
        printf(format,root->val);
        if (root->left)  
            preOrderTraverse(root->left);  
        if (root->right)  
            preOrderTraverse(root->right);  
    }  

/*非递归*/
void preOrderTraverse(TreeNode* root){
    stack<TreeNode*> nodeStack;  //使用栈
    nodeStack.push(root);
    TreeNode* node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
        printf(format, node->val); 
        nodeStack.pop();
        if(node->right){
            nodeStack.push(node->right);  //先将右子树压栈
        }
        if(node->left){
            nodeStack.push(node->left);  //再将左子树压栈
        }
    }
}

(2)中序遍历

/*递归*/
void inOrderTraverse(TreeNode* root) {  
        if (root->left)  
            inOrderTraverse(root->left);  
        printf(format,root->val);
        if (root->right)  
           inOrderTraverse(root->right);  
    }  

/*非递归*/
void inOrderTraverse(TreeNode* root){
        stack<TreeNode*> nodeStack; //使用栈 
        TreeNode* currentNode = root;  
        while (currentNode || !nodeStack.empty()){    
            if (currentNode) {  
                nodeStack.push(currentNode);  
                currentNode = currentNode->left;  
            }
            else
            {
                currentNode = nodeStack.top();
                nodeStack.pop();
                printf(format,root->val);
                currentNode = currentNode->right;  
            }  
        }     
}

(3)后序遍历

/*递归*/
void postOrderTraverse(TreeNode* root) {  
        if (root->left)  
           postOrderTraverse(root->left);
        if (root->right)  
          postOrderTraverse(root->right);    
        printf(format,root->val);
    }  

/*非递归*/
void postOrderTraverse(TreeNode* root) {  
        stack<TreeNode*node>nodeStack; //使用栈
        TreeNode* currentNode = root;  
        TreeNode* rightNode = null;  
        while (currentNode|| !stack.empty()) {  
            // 一直循环到二叉排序树最左端的叶子结点
            while (currentNode) {  
                nodeStack.push(currentNode);  
                currentNode = currentNode->left;  
            } 
            currentNode = stack.top();
            stack.pop();  
            // 当前结点没有右结点或上一个结点(已经输出的结点)是当前结点的右结点,则输出当前结点  
            while (currentNode.right == null || currentNode.right == rightNode) {  
                printf(format,root->val);
                rightNode = currentNode;  
                if (stack.isEmpty()) {  
                    return; //root以输出,则遍历结束
                    }  
                 currentNode = stack.top();
                 stack.pop();  
            }  
            stack.push(currentNode); //还有右结点没有遍历  
            currentNode = currentNode->right;  
        }  
    }

 

参考

http://www.javashuo.com/article/p-nydqblop-kz.html