复制二叉树

【算法步骤】

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

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

  递归复制左子数。

  递归复制右子数。

【算法描述】

 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 }

 

版权声明:本文为didiaodidiao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/didiaodidiao/p/9132863.html