二叉树梳理

来源:互联网 发布:如何判定论文数据造假 编辑:程序博客网 时间:2024/06/03 19:04

本篇文章主要涉及到

  • 二叉树的非递归遍历(ForwardTravesal()/MiddleTravesal()
  • 二叉树的深度: DepthOfTree()
  • 二叉树的叶子节点个数: CountsOfLeaves()

二叉树的非递归需要借助,原因在于递归遍历思想是基于的,现在要变为非递归,需要借助额外空间,空间换时间。

  • 关于二叉树的递归遍历(RecursiveTravesal)见博文
    Python实现二叉树遍历

  • 前序遍历ForwardTravesal()—–根左右
    1.当前节点p,访问p->data将p存入Stack
    2.若p->left存在,将p->left作为当前的p;若不存在,将栈顶元素出栈,再将p->right作为当前的p
    3.栈空即为结束
void NonRecursiveForward(BiTree root){    BiTree p = root;    int depth = DepthOfTree(root);    BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);    int top = -1;    while(p != NULL || top != -1)    {        while(p != NULL)        {            cout<<p->data<<" ";            stack[++top] = p;            p = p->left;        }        if(top != -1)        {            p = stack[top--];            p = p->right;        }    }    cout<<endl;}

  • 中序遍历MiddleTravesal()—–左根右
    注:中序遍历与前序遍历输出时机不同,相信大家秒懂。
void NonRecursiveMiddle(BiTree root){    BiTree p = root;    int depth = DepthOfTree(root);    BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);    int top = -1;    while(p != NULL || top != -1)    {        while(p != NULL)        {            stack[++top] = p;            p = p->left;        }        if(top != -1)        {            p = stack[top--];            cout<<p->data<<" ";            p = p->right;        }    }    cout<<endl;}

二叉树的深度,可以采用递归来解决,通俗易懂。

树的深度等于当前节点深度 = 1 + 子树(左子树和右子树最大深度)深度

/*** get depth of tree*/int DepthOfTree(BiTree root){    int deep = 0;    if (root)    {        int leftDepth = DepthOfTree(root->left);        int rightDepth = DepthOfTree(root->right);        deep = leftDepth >= rightDepth ? leftDepth+1 : rightDepth+1;    }    return deep;}

二叉树叶子节点个数等价于

满足left == NULL && right == NULL的节点
同理,知道叶子节点个数就会知道度为2的节点个数

/*** get counts of leaves*/int CountsOfLeaves(BiTree root){    //int count = 0;    if (!root)        return 0;    if (root->left == NULL && root->right == NULL)    {        return 1;    }    int lc = CountsOfLeaves(root->left);    int rc = CountsOfLeaves(root->right);    return (lc+rc);}

二叉树按层遍历TravesalByLayer(),同样需要借助额外空间

利用队列先进先出的特性,可以实现,爱思考的大家动手吧。


心得

经过一个多月的面试,遇到算法题中二叉树相关的比较多,比如左右子树相交的第一个节点,堆排序的树结构链表实现等。总的来说,树说难不难,说易不易,理解其中的编程思想很重要。


完整代码

#include <iostream>using namespace std;typedef int DataType;typedef struct node{    DataType data;    struct node *left;    struct node *right;}BTNode, *BiTree;int CreateABinaryTree(BiTree *t){    // static count = 0;    *t = (BiTree)malloc(sizeof(BTNode));    if (!(*t))    {        /* can't create tree */        exit(-1);    }    DataType dt;    cin>>dt;    if (dt == -1)    {        /* code */        *t = NULL;    }else    {        (*t)->data = dt;        cout<<"You can input data to left (Root is "<<dt<<"): "<<endl;        CreateABinaryTree(&((*t)->left));        cout<<"You can input data to right (Root is "<<dt<<"): "<<endl;        CreateABinaryTree(&((*t)->right));    }    return 1;}/**** Traversal with Recursive to BTree**/void RecursiveRootLeftRight(BiTree root){    if (root)    {        /* code */        cout<<root->data<<" ";        RecursiveRootLeftRight(root->left);        RecursiveRootLeftRight(root->right);    }}void RecursiveLeftRootRight(BiTree root){    if (root)    {        /* code */        RecursiveLeftRootRight(root->left);        cout<<root->data<<" ";        RecursiveLeftRootRight(root->right);    }}void RecursiveLeftRightRoot(BiTree root){    if (root)    {        /* code */        RecursiveLeftRightRoot(root->left);        RecursiveLeftRightRoot(root->right);        cout<<root->data<<" ";    }}/*** get depth of tree*/int DepthOfTree(BiTree root){    int deep = 0;    if (root)    {        int leftDepth = DepthOfTree(root->left);        int rightDepth = DepthOfTree(root->right);        deep = leftDepth >= rightDepth ? leftDepth+1 : rightDepth+1;    }    return deep;}/*** get counts of leaves*/int CountsOfLeaves(BiTree root){    //int count = 0;    if (!root)        return 0;    if (root->left == NULL && root->right == NULL)    {        return 1;    }    int lc = CountsOfLeaves(root->left);    int rc = CountsOfLeaves(root->right);    return (lc+rc);}/**** Traversal with Non-Recursive to BTree**/void NonRecursiveForward(BiTree root){    BiTree p = root;    int depth = DepthOfTree(root);    BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);    int top = -1;    while(p != NULL || top != -1)    {        while(p != NULL)        {            cout<<p->data<<" ";            stack[++top] = p;            p = p->left;        }        if(top != -1)        {            p = stack[top--];            p = p->right;        }    }    cout<<endl;}void NonRecursiveMiddle(BiTree root){    BiTree p = root;    int depth = DepthOfTree(root);    BiTree *stack = (BiTree *)malloc(sizeof(BiTree)*depth);    int top = -1;    while(p != NULL || top != -1)    {        while(p != NULL)        {            stack[++top] = p;            p = p->left;        }        if(top != -1)        {            p = stack[top--];            cout<<p->data<<" ";            p = p->right;        }    }    cout<<endl;}int main(int argc, char const *argv[]){    cout<<"Datasource fo Tree "<<endl;    BiTree root;    /** create a binary tree */    CreateABinaryTree(&root);    cout<<"Binary Tree is created well."<<endl;    cout<<"Depth Of Tree: "<<DepthOfTree(root)<<endl;    cout<<"Counts Of Leaves: "<<CountsOfLeaves(root)<<endl;    /** Forward Traversal */    cout<<"*** Recursive Forward Traversal ***"<<endl;    RecursiveRootLeftRight(root);    cout<<endl;    /** Middle Traversal */    cout<<"*** Recursive Middle Traversal ***"<<endl;    RecursiveLeftRootRight(root);    cout<<endl;    /** Backward Traversal */    cout<<"*** Recursive Backward Traversal ***"<<endl;    RecursiveLeftRightRoot(root);    cout<<endl;    cout<<"*** Non-Recursive Forward Traversal ***"<<endl;    NonRecursiveForward(root);    cout<<"*** Non-Recursive Middle Traversal ***"<<endl;    NonRecursiveMiddle(root);    return 0;}
0 0
原创粉丝点击