二叉树的三种遍历的递归与非递归算法

今天复习了一下二叉树的前序遍历、中序遍历、后序遍历的递归与非递归算法,顺便记录一下:

//TreeTest.h
#include <iostream>
struct TreeNode
{
    int value;
    TreeNode* leftChild;
    TreeNode* rightChild;
    void print()
    {
        printf("%d ",value);
    }

};
class MyTree
{
private:
    TreeNode* m_root;
    TreeNode* create(TreeNode*& root);
    void destroy(TreeNode* root);
    void preOrderRecursive(TreeNode* root);
    void inOrderRecursive(TreeNode* root);
    void postOrderRecursive(TreeNode* root);
    void levelOrderRecursive(TreeNode* root);
public:
    MyTree();
    ~MyTree();
    TreeNode* getTreeNode(int value);
    void createTreeForPreOrder();
    void preOrderRecursive();
    void inOrderRecursive();
    void postOrderRecursive();
    void levelOrderRecursive();

    //非递归遍历
    void preOrderUnRecursive();
    void inOrderUnRecursive();
    void postOrderUnRecursive();
};

//TreeTest.cpp
#include "TreeTest.h"
#include <iostream>
#include <queue>
#include <stack>
using namespace std;

MyTree::MyTree() : m_root(NULL)
{
}
MyTree::~MyTree()
{
    this->destroy(m_root);
    m_root = NULL;
}
void MyTree::destroy(TreeNode* root)
{
    if (!root) return;
    TreeNode* left=NULL, *right=NULL;

    left = root->leftChild;
    right = root->rightChild;
    delete root;

    if (left) destroy(left);
    if (right) destroy(right);
}

TreeNode* MyTree::create(TreeNode*& root)
{
    int value;
    cin>>value;
    if (value <= 0) return NULL;  //小于或等于0代表NULL
    if (!root)
       root = this->getTreeNode(value);
    if (!root->leftChild)
        this->create(root->leftChild);
    if (!root->rightChild)
        this->create(root->rightChild);
    return root;
}

TreeNode* MyTree::getTreeNode(int value)
{
    TreeNode* p = new TreeNode();
    p->value = value;
    p->leftChild = p->rightChild = NULL;
    return p;
}

void MyTree::createTreeForPreOrder()
{
    this->create(m_root);
}

void MyTree::preOrderRecursive(TreeNode* root)
{
    if (!root) return;
    printf("%d ",root->value);
    if (root->leftChild) this->preOrderRecursive(root->leftChild);
    if (root->rightChild) this->preOrderRecursive(root->rightChild);
}

void MyTree::inOrderRecursive(TreeNode* root)
{
    if (!root) return;
    if (root->leftChild) this->inOrderRecursive(root->leftChild);
    printf("%d ",root->value);
    if (root->rightChild) this->inOrderRecursive(root->rightChild);
}

void MyTree::postOrderRecursive(TreeNode* root)
{
    if (!root) return;
    if (root->leftChild) this->postOrderRecursive(root->leftChild);
    if (root->rightChild) this->postOrderRecursive(root->rightChild);
    printf("%d ", root->value);
}

void MyTree::levelOrderRecursive(TreeNode* root)
{
    queue<TreeNode*> Q;
    if (root) Q.push(root);
    while (!Q.empty())
    {
        TreeNode* node = Q.front();
        Q.pop();
        node->print();
        if (node->leftChild) Q.push(node->leftChild);
        if (node->rightChild) Q.push(node->rightChild);
    }
}

void MyTree::preOrderRecursive()
{
    printf("递归前序遍历:");
    this->preOrderRecursive(m_root);
    printf("\n");
}
void MyTree::inOrderRecursive()
{
    printf("递归中序遍历:");
    this->inOrderRecursive(m_root);
    printf("\n");
}
void MyTree::postOrderRecursive()
{
    printf("递归后序遍历:");
    this->postOrderRecursive(m_root);
    printf("\n");
}
void MyTree::levelOrderRecursive()
{
    printf("层序遍历:");
    this->levelOrderRecursive(m_root);
    printf("\n");
}

void MyTree::preOrderUnRecursive()
{
    if (!m_root) return;
    printf("非递归先序遍历:");
    stack<TreeNode*> S;
    S.push(m_root);
    while (!S.empty())
    {
        TreeNode* node = S.top();
        S.pop();
        node->print();
        if (node->rightChild) S.push(node->rightChild);
        if (node->leftChild) S.push(node->leftChild);
    }
    printf("\n");
}
void MyTree::inOrderUnRecursive()
{
    if (!m_root) return;
    printf("非递归中序遍历:");
    stack<TreeNode*> S;
    TreeNode* p = m_root;

    while (p || !S.empty())
    {
        while (p)
        {
            S.push(p);
            p = p->leftChild;
        }

        p = S.top();
        S.pop();
        p->print();

        /*由于是中序遍历,那么访问了当前节点后,
        下一步必定要访问该节点的右子树*/
        p = p->rightChild;
    }
    printf("\n");
}
void MyTree::postOrderUnRecursive()
{
    if (!m_root) return;
    printf("非递归后序遍历:");
    stack<TreeNode*> S;
    TreeNode* p = m_root;
    TreeNode* q = NULL;
    while (p || !S.empty())
    {
        while (p)
        {
            S.push(p);
            p = p->leftChild;
        }

        p = S.top();

        /*
        判断表示当前节点的右节点没有或已经访问过
        q表示上一次访问的节点,由于是后续遍历,
        若当前节点有右节点,那么上一次访问的节点一定是当前节点的右节点
        */
        if (!p->rightChild || p->rightChild == q)
        {
            p->print();
            q = p;
            p = NULL;
            S.pop();
        }
        else
        {
            p = p->rightChild;
        }
    }
    printf("\n");
}
//main.cpp
#include "TreeTest.h"
int main()
{
    MyTree tree;

    tree.createTreeForPreOrder();
    tree.preOrderRecursive();
    tree.preOrderUnRecursive();
    tree.inOrderRecursive();
    tree.inOrderUnRecursive();
    tree.postOrderRecursive();
    tree.postOrderUnRecursive();
    tree.levelOrderRecursive();

    getchar();
    getchar();
    return 0;
}

测试用例:

1 2 3 -1 -1 4 -1 -1 5 6 -1 -1 7 8 -1 -1 9 -1 -1

时间: 2024-10-22 05:00:51

二叉树的三种遍历的递归与非递归算法的相关文章

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree; import java.util.Stack; public class BiTree { public static void main(String[] args) { // 首先构造叶子节点 BiTree leafA1 = new BiTree(4); BiTree leafA2 = new BiTree(5); BiTree leafB1 = new BiTree(6); BiTree leafB2 = new BiTree(7)

java实现二叉树的三种遍历算法(递归)

一,定义一个节点类: package test; public class Node { private int data; private Node left; private Node right; public Node(int data) { this.data = data; } public int getData() { return data; } public void setData(int data) { this.data = data; } public Node ge

二叉树的三种遍历方式的循环和递归的实现方式

///////////////////头文件:BST.h//////////////////////// #ifndef BST_H #define BST_H #include "StdAfx.h" #include<iostream> #include<stack> template<typename DataType> class BST { public: class Node { public: Node(int data=0):m_dat

二叉树的三种遍历简单版

同学突然向我问二叉树的三种遍历代码.数据结构刚刚学了,自己很吃力的敲了出来. 和老师演示的代码有很大差距. #include <stdio.h>#include <string.h>#include <stdlib.h> #define Error -1#define Right 1 struct BiTnode{    char data;    struct BiTnode *LChild;    struct BiTnode *RChild; }; BiTnode

公交车站捡垃圾之二叉树的三种遍历方法

# 二叉树的遍历 今天下午看了二叉树的三种遍历方式,虽然能写出代码,但是理解可能不太到位,感觉很容易忘,所以想到一个形象的方法,把每个节点当作公交车站,而访问节点则是在这个公交车站捡垃圾,右子树和左子树则表示岔路.然后这个捡垃圾的人钟爱左边这个方向,所以一直以左优先.甲乙丙三个人,都爱捡垃圾,但是思考方式不同,所以捡垃圾的方法有点不同. 先序遍历 先序遍历最简单,秉承的原则是,甲很小心谨慎,每次经过公交车站,怕别人捡了,都把垃圾先捡到手,直到左边的路走完了,再往回走,但是回来的过程中,在公交车站

PTA 二叉树的三种遍历(先序、中序和后序)

6-5 二叉树的三种遍历(先序.中序和后序) (6 分) 本题要求实现给定的二叉树的三种遍历. 函数接口定义: void Preorder(BiTree T); void Inorder(BiTree T); void Postorder(BiTree T); T是二叉树树根指针,Preorder.Inorder和Postorder分别输出给定二叉树的先序.中序和后序遍历序列,格式为一个空格跟着一个字符. 其中BinTree结构定义如下: typedef char ElemType; typed

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树的前序、中序、后序遍历的递归和非递归算法实现

1 /** 2 * 二叉树的前序.中序.后序遍历的递归和非递归算法实现 3 **/ 4 5 //二叉链表存储 6 struct BTNode 7 { 8 struct BTNode *LChild; // 指向左孩子指针 9 ELEMENTTYPE data; // 结点数据 10 struct BTNode *RChild; // 指向右孩子指针 11 }; 12 13 /** 14 * 前序遍历 15 **/ 16 // 递归实现 17 void PreorderTraversal(BTNo

算法学习 - 树的三种遍历(递归实现)先序遍历,中序遍历,后序遍历

树的遍历 这三种遍历方法其实都很简单的,举例来说: a / b c 这个是例子下面讲下这三个是如何遍历的. struct TreeNode; typedef TreeNode* Node; typedef int EleType; struct TreeNode{ Node lchild; Node rchild; EleType data; }; 先序遍历 先序遍历,就是从上到下,从左到右,遇到一个就遍历,上面这个例子遍历的序列就是:a b c 递归代码如下: void PreOrderTre