二叉树的定义及实现

来源:互联网 发布:超级电子仿真软件 编辑:程序博客网 时间:2024/06/05 15:28

树形结构是一类重要的非线性结构。树形结构是结点之间有分支,并具有层次关系的结构。它非常类似于自然界中的树。

二叉树的递归定义
 二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。
 
二叉树的图论定义
二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。

代码实现:

/*数据结构:tree功能:      creat() 创建树 (把树结点放入vector中,以层次遍历的形式导入树,#代表当前结点为空)      TLR() 前序遍历二叉树      LTR() 中序遍历二叉树      LRT() 后序遍历二叉树      deep() 求树的深度      leaf() 求树的叶子结点个数      remove() 消除二叉树(不等同于析构)/************ 暂时未实现************//* addSubtree(iter,tree)  //在某个结点增加一颗子树 removeSubtree (iter)  //删除以iter结点为root的子树 invertBinaryTree() 翻转一棵二叉树                        判断二叉树是不是完全二叉树                        求两个节点的最低公共祖先节点;*/#include<iostream>#include<vector>#include<queue>#include<stack>#include<cmath>template<typename type>class Tnode{public:    type data;    Tnode<type> *left;    Tnode<type> *right;    Tnode<type>():data(0),left(NULL),right(NULL){}    Tnode<type>(type data):data(data),left(NULL),right(NULL){}};template<typename type>class Tree{private:    unsigned Deep;public:    Tnode<type> *root;    Tree():root(NULL),Deep(0){};    ~Tree()    {        remove(root);    }    void creat(std::vector<type> R)  /*  因为用'#'作为 空 的标记,所以type暂时只能为整数型,如有需求可进行更改    */    {        Deep = log(R.size())/log(2)+1;        //std::cout<<"树有 "<<Deep<<" 层"<<std::endl;        root = new Tnode<type>(R[0]);        Tnode<type> *temp = root;       //建立根节点        std::queue<Tnode<type>*> flag;  //存储还没有处理孩子的结点        flag.push(root);        int temp2 = 1;    //层次遍历的第n个元素        while(!flag.empty())        {            if (R[2*temp2-1]=='#')            {              temp->left = NULL;              //std::cout<<"第 "<<temp2<<"个结点的左孩子为空"<<std::endl;            }                else                {                  temp->left = new Tnode<type>(R[2*temp2-1]);                  if(2*temp2-1<=pow(2,Deep-1)-1)  //只需要存储到倒数第二层                  flag.push(temp->left);                 // std::cout<<"第 "<<temp2<<"个结点的左孩子为"<<R[2*temp2-1]<<"  "<<std::endl;                }            if (R[2*temp2]=='#')            {              temp->right = NULL;             // std::cout<<"第 "<<temp2<<"个结点的右孩子为空"<<std::endl;            }                else                {                  temp->right = new Tnode<type>(R[2*temp2]);                  if(2*temp2<=pow(2,Deep-1)-1)                  flag.push(temp->right);                  //std::cout<<"第 "<<temp2<<"个结点的左孩子为"<<R[2*temp2]<<"  "<<std::endl;                }            temp2++;            flag.pop();            temp = flag.front();        }    }void TLR(Tnode<type> *root) {   //前序遍历递归    if (root) {        std::cout<<root->data<<" ";        TLR(root->left);        TLR(root->right);    }}void LTR(Tnode<type> *root) {   //中序遍历递归    if (root) {        LTR(root->left);        std::cout<<root->data<<" ";        LTR(root->right);    }}void LRT(Tnode<type> *root) {   //后序遍历递归    if (root) {        LRT(root->left);        LRT(root->right);        std::cout<<root->data<<" ";    }}/************* 三序遍历非递归版重载 ***********/void TLR() {   //前序遍历    if(!root) {std::cout<<"空树"<<std::endl;}    Tnode<type> *R = root;    std::stack<Tnode<type>*> tem;    while(R||!tem.empty())    {        if(R)        {            std::cout<<R->data<<" ";            tem.push(R);            R = R->left;        }        else        {        R = tem.top();        tem.pop();        R = R->right;        }    }}void LTR() {   //中序遍历    if(!root) {std::cout<<"空树"<<std::endl;}    Tnode<type> *R = root;    std::stack<Tnode<type>*> tem;    while(R||!tem.empty())    {        if(R)        {            tem.push(R);            R = R->left;        }        else //R为空        {        R = tem.top();        tem.pop();        std::cout<<R->data<<" ";        R = R->right;        }    }}void LRT() {   //后序遍历   后序遍历LRT有两种情况,第一种是右子树已访问,则直接访问根节点。第二种是右子树未访问,则先访问右子树再访问根节点    Tnode<type> *R = root;    Tnode<type> *pre = NULL;    std::stack<Tnode<type>*> tem;   while(R||!tem.empty())    {        while(R)        {          tem.push(R);          R=R->left;        }        R = tem.top();      if(R->right==pre||R->right==NULL)  //访问R节点的条件 ,也是左右结点都访问完过的结点        {           std::cout<<R->data<<" ";           pre = R;           tem.pop();           R = NULL;        }        else          R=R->right;    }}unsigned deep(){    return Deep;}unsigned leaf(Tnode<type> *root){int m,n;if(!root) return 0;if(!root->left&&!root->right) return 1;else{    m=leaf(root->left);    n=leaf(root->right);    return m+n;}}void remove(Tnode<type> *root){if(root){  remove(root->left);  remove(root->right);  delete root;}  this->root = NULL;}};

参考资料http://student.zjzk.cn/course_ware/data_structure/web/shu/shu6.2.1.htm
https://baike.baidu.com/item/%E4%BA%8C%E5%8F%89%E6%A0%91/1602879?fr=aladdin