复制二叉树

【算法步骤】

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

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

  递归复制左子数。

  递归复制右子数。

【算法描述】

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

计算二叉树的深度。

【算法步骤】

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

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

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

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

【算法描述】

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

统计二叉树中结点个数。

【算法步骤】

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

【算法描述】

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

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

【算法思想】

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

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

【算法描述】

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

判断两颗树是否相等。

【算法思想】

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

【算法描述】

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

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

【算法思想】

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

【算法描述】

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

 

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

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

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

【算法思想】

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

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

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

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

【算法思想】

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

【算法描述】

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

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

【算法思想】

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

【算法描述】

  1. 1 int Level(BiTree T)
  2. 2 {//层次遍历二叉树,并统计树中度为1的结点的个数
  3. 3 cout<<endl<<endl<<"用按层次遍历二叉树的方法,统计树中度为1的结点数目:"<<endl;
  4. 4 int count = 0;//count为树中度为1的结点数目
  5. 5 if(T)
  6. 6 {
  7. 7 queue<BiTree> s;
  8. 8 BiTree p;
  9. 9 BiTree q;
  10. 10
  11. 11 p = T;
  12. 12 s.push(p);//将根节点入队
  13. 13 while(!s.empty())
  14. 14 {
  15. 15 p = s.front(); //p出队访问结点
  16. 16 s.pop();
  17. 17 cout<<p->data<<ends;//访问出队的结点
  18. 18
  19. 19 if( (p->lchild && !p->rchild) || ( !p->lchild && p->rchild ) )
  20. 20 count++;
  21. 21
  22. 22 if(p->lchild != NULL)//如果左节点不为空 左节点入队
  23. 23 {
  24. 24 q = p->lchild;
  25. 25 s.push(q);
  26. 26
  27. 27 }
  28. 28 if(p->rchild != NULL)//如果右节点不为空 左节点入队
  29. 29 {
  30. 30 q = p->rchild;
  31. 31 s.push(q);
  32. 32
  33. 33 }
  34. 34
  35. 35
  36. 36 }
  37. 37
  38. 38 }
  39. 39 return count;
  40. 40
  41. 41 }

 

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