• 关于二叉树的题


    复制二叉树

    【算法步骤】

    如果是空树,递归结束,否则执行以下操作:

      申请一个新结点空间,复制根结点。

      递归复制左子数。

      递归复制右子数。

    【算法描述】

     1 //复制二叉树(递归)
     2 void Copy(BiTree T, BiTree &NewT)
     3 {//复制一颗和T完全相同的二叉树
     4     if(T == NULL)//如果是空数,递归结束
     5     {
     6         NewT = NULL;
     7         return;
     8     }
     9     else 
    10     {
    11         NewT = new BiTNode;
    12         NewT->data = T->data;//复制根节点
    13         Copy(T->lchild, NewT->lchild);//递归复制左指数
    14         Copy(T->rchild, NewT->rchild);//递归复制右指数
    15     }//else
    16 }

    计算二叉树的深度。

    【算法步骤】

    如果是空树,递归结束,否则执行以下操作:

      ●递归计算左子数的深度记为m。

      ●递归计算右子数的深度记为n。

      ●如果m大于n,二叉树的深度为m+1,否则为n+1。

    【算法描述】

     1 //计算二叉树的深度
     2 int Depth(BiTree T)
     3 {//计算二叉树T的深度
     4     int m,n;
     5     if(T == NULL)return 0;//如果是空数,深度为0,递归结束
     6     else
     7     {
     8         m = Depth(T->lchild);//递归计算左指数的深度计为m
     9         n = Depth(T->rchild);//递归计算右指数的深度计为n
    10         if(m>n) return(m+1);//二叉树的深度为m与n的较大者加1
    11         else     return n+1;
    12     }//else
    13     
    14 }

    统计二叉树中结点个数。

    【算法步骤】

    如果是空数,则结点个数为0;否则,结点个数为左子数的节点个数加上右子数的节点个数在加1。

    【算法描述】

    1 //统计二叉树中节点的个数
    2 int NodeCount(BiTree T)
    3 {//统计二叉树中节点T的个数
    4     if(T == NULL) return 0;//如果是空数,则节点个数为0,递归结束
    5     else return NodeCount(T->lchild) + NodeCount(T->rchild) +1;//否则节点个数为左子数的节点个数+右子数的节点个数+1
    6     
    7 }

     统计二叉树的叶节点个数。

    【算法思想】

           利用递归实现,递归结束的条件有两个:一个是二叉树为空,另一个是遇到叶子节点。当二叉树为空时,递归结束返回0;当二叉树不为空,且左、右子树为空(页子结点)时,递归结束返回1;

    当二叉树不为空,且左、右子树不同时为空(非叶子节点),递归调用统计函数,返回左子树中叶子节点个数加上右子树中叶子节点个数。

    【算法描述】

    1 int LeafNode(BiTree T)
    2 {//统计二叉树T中叶子节点个数
    3     if(T == NULL)//空数返回0
    4         return 0;
    5     else if(T->lchild == NULL && T->rchild == NULL)//叶子节点返回1
    6         return 1;
    7     else                                              //递归
    8         return LeafNode(T->lchild)+LeafNode(T->rchild);
    9 }

    判断两颗树是否相等。

    【算法思想】

           利用递归实现,递归结束条件有3个:一是两棵树均为空,返回相等;二是只有一棵树为空,返回不等;三是结点数据域不等,返回不等。其他情况下则递归判断相应的孩子节点是否相等。

    【算法描述】

     1 bool CmpTree(BiTree T1, BiTree T2)
     2 {//判断两颗二叉树是否相等
     3     if(T1 == NULL && T2 == NULL)//都为NULL,相等
     4         return true;
     5     else if(T1 == NULL || T2 == NULL)//只有一个为NULL,不等
     6         return false;
     7     else if(T1->data != T2->data)//跟结点不相等,直接返回不等否则递归结束
     8         return false;
     9     else return CmpTree(T1->lchild, T2->lchild)&&CmpTree(T1->rchild, T2->rchild);
    10         
    11 }

    交换二叉树每个节点的左孩子和右孩子

    【算法思想】

    如果某节点的左、右子树有一个为空,则返回,否则交换该结点的左、右孩子节点,然后递归交换左、右子树。

    【算法描述】

     1 void ChangeLR(BiTree &T)
     2 {//交换二叉树每个节点的左孩子和右孩子
     3     
     4     if(T->lchild == NULL || T->rchild == NULL)//左右孩子有一个为空返回
     5         return;
     6     else//交换左右孩子节点
     7     {
     8         
     9         //直接交换指针
    10         BiTree temp = T->lchild;
    11         T->lchild = T->rchild;
    12         T->rchild = temp;
    13     
    14     }//递归
    15     ChangeLR(T->lchild);
    16     ChangeLR(T->rchild);
    17 
    18 }

    这个是另一种交换方法(不满足题意)

     1 void ChangeLR(BiTree &T)
     2 {//交换二叉树每个节点的左孩子和右孩子
     3     
     4     if(T->lchild == NULL || T->rchild == NULL)//左右孩子有一个为空返回
     5         return;
     6     else//交换左右孩子节点
     7     {
     8         
     9 
    10         //交换左右值
    11         BiTree p, q;
    12         ElemType temp;
    13         p = T->lchild;
    14         q = T->rchild;
    15         temp = p->data;
    16         p->data = q->data;
    17         q->data = temp;    
    18         
    19     }//递归
    20     ChangeLR(T->lchild);
    21     ChangeLR(T->rchild);
    22 
    23 }

      设计二叉树的双序遍历算法(双序遍历是指对于二叉树的每一个结点来说,先访问这个结点,再按双序遍历它的左子树,然后再一次访问这个结点,接下来按双序遍历它的右子树)。

    【算法思想】

    双序遍历与先序遍历相比,只是多了一次访问,即在递归遍历其左子树后再访问一次该结点。

    因此,
    步骤如下:
         若二叉树为空,则空操作;否则:
         (1)访问根结点;
         (2)先序遍历左子树;
         (3)访问根结点;
         (4)先序遍历右子树。
    【算法描述】

     1 void DoubleTraverse(BiTree T)
     2 {//双序遍历二叉树T的递归算法
     3     if(T)//若二叉树非空
     4     {
     5         cout<<T->data<<ends;//访问根节点
     6         DoubleTraverse(T->lchild);//双序遍历左子数
     7         cout<<T->data<<ends;//访问根节点
     8         DoubleTraverse(T->rchild);//双序遍历右子数
     9     }
    10 }

    计算二叉树最大的宽度(二叉树的最大宽度是指二义树所有层中结点个数的最大值)。

    【算法思想】

    计算二叉树最大的宽度可采用层次遍历的方法,利用队列来实现。首先判断是否为空树,如果为空树则宽度为0;不为空则分别记录局部的宽度和当前的最大宽度,逐层遍历结点,如果结点有孩子结点,则将其孩子加人队尾;每层遍历完毕之后,若局部宽度大于当前的最大宽度,则修改最大宽度。

    【算法描述】

     1 int Width(BiTree T)
     2 {//求二叉树T的最大宽度
     3     if(T == NULL)//如果数为空宽度为零
     4         return 0;
     5     else
     6     {
     7         BiTree p;
     8         BiTree Q[10000];//Q是队列,元素为二叉数结点指针,容量足够大
     9         int front = 1;//队头指针
    10         int rear = 1;//队尾指针
    11         int last = 1;//同层最后结点的位置
    12         int maxW = 0;//最大宽度
    13         int temp = 0;//局部宽度
    14         
    15         Q[rear] = T;
    16         while(front <= last)
    17         {
    18             p = Q[front++];
    19             temp++;
    20             
    21             if(p->lchild != NULL)//左子数入队
    22                 Q[++rear] = p->lchild;
    23             if(p->rchild != NULL)//右子数入队
    24                 Q[++rear] = p->rchild;//一层结束
    25             
    26             if(front > last)
    27             {
    28                 last = rear;
    29                 if(temp > maxW)
    30                     maxW = temp;
    31                 temp = 0;
    32             }//if
    33             
    34         }//while
    35         
    36         return maxW;
    37         
    38     }
    39     
    40 }

    用按层次顺序遍历又树的方法, 统计树中度为I的结点数目。

    【算法思想】

    可以借助队列实现层次顺序遍历二叉树。从根结点开始,首先将结点进队,然后依次访问队列中的结点,访问之后将其出队。若该结点左子树为空、右子树非空或者右子树为空、左子树非空,则该结点为度为1的结点,计数加1,并将该结点的非空孩子结点人队,直到队列为空则统计结束。

    【算法描述】

     1 int Level(BiTree T)
     2 {//层次遍历二叉树,并统计树中度为1的结点的个数
     3     cout<<endl<<endl<<"用按层次遍历二叉树的方法,统计树中度为1的结点数目:"<<endl;
     4     int count = 0;//count为树中度为1的结点数目
     5     if(T)
     6     {
     7         queue<BiTree> s;
     8         BiTree p;
     9         BiTree q;
    10         
    11         p = T;
    12         s.push(p);//将根节点入队
    13         while(!s.empty())
    14         {
    15             p = s.front();   //p出队访问结点
    16             s.pop();
    17             cout<<p->data<<ends;//访问出队的结点
    18 
    19             if( (p->lchild && !p->rchild) || ( !p->lchild && p->rchild ) )
    20                 count++;
    21 
    22             if(p->lchild != NULL)//如果左节点不为空  左节点入队
    23             {
    24                 q = p->lchild;
    25                 s.push(q);
    26                 
    27             }
    28             if(p->rchild != NULL)//如果右节点不为空  左节点入队
    29             {
    30                 q = p->rchild;
    31                 s.push(q);
    32                 
    33             }
    34                         
    35             
    36         }
    37         
    38     }
    39     return count;
    40     
    41 }
  • 相关阅读:
    如何选择开源许可证?(转)
    gdb的使用(转)
    git的使用
    2017-3-13 leetcode 4 11 15
    2017-3-12 leetcode 167 209 216
    2017-3-11 leetcode 217 219 228
    2017-3-10 leetcode 229 238 268
    1175: 零起点学算法82——find your present
    1174: 零起点学算法81——求整数绝对值
    1173: 零起点学算法80——求实数绝对值
  • 原文地址:https://www.cnblogs.com/didiaodidiao/p/9132863.html
Copyright © 2020-2023  润新知