ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1-树-遍历、翻转、对称

2022-07-10 09:02:37  阅读:227  来源: 互联网

标签:lchild 遍历 curr Sq 对称 rchild root Se 翻转


1-1 二叉树遍历

1-1-1 非递归遍历\先中后 - 源码

先序遍历 -- 根左右

  1. 思想
    使用栈的左中右遍历;
    先访问根节点,再入栈以待访问右节点;
    每次的当前节点为null时,进入遍历右节点次序;

  2. 代码

// pre
void preOrder_N(BiTNode *T){
    SqStack Sq;
    initStack(Sq);
    BiTNode *p = T;
    while (p || !isEmpty(Sq)){
        if(p){
            visit(p);
            Push(Sq, p);
            p = p->lchild;
        }
        else{
            Pop(Sq, p);
            p = p->rchild;
        }
    }
}

中序遍历 -- 左根右

  1. 思想
    遍历思想和先序遍历类似:因为从顺序来讲都是先从左根到左再向右,只是将访问函数放在了即将pop的结点上;
  2. 代码
// in
void inOrder(BiTNode *T){
    SqStack Sq;
    initStack(Sq);
    BiTNode *p = T;
    while (p || !isEmpty(Sq)){
        if(p){
            Push(Sq, p);
            p = p->lchild;
        }else{
            Pop(Sq, p);
            visit(p);
            p = p->rchild;
        }
    }
}

后序 -- 左右根

  1. 思想
    同样使用栈的结构,每次得到左右结点都进栈之后开始遍历该根节点;

    需要注意的是

    右节点的入栈需要条件:

    1.左到头

    2. 右孩子存在&右孩子不为最近访问过(防止右右打转)

    访问结点: 1. 访问 2.最近rct 3.p设置为空

  2. 代码

具体代码实现
// post
void postOrder(BiTNode *T){
    BiTNode *p = T, *rct = nullptr;
    SqStack Sq;
    initStack(Sq);
    while (p || !isEmptySq(Sq)){
        if(p){
            Push(Sq, p);
            p = p->lchild;
        }else{
            Pop(Sq, p);
            if(p->rchild && p->rchild != rct) 
            // 需要注意右结点存在 && 最近没有访问过
            {
                Push(Sq, p);
                p = p->rchild;
            }else{  // 访问结点的条件在于左右孩子都空,
                visit(p);
                rct = p;
                p = nullptr;
            }
        }
    }
}

1-1-2层序 -- 队列

  1. 思想
    使用队列先将结点入队,

    • TODO
  2. 代码

具体代码实现
void LayerOrder(BiTNode *T){
    SeQueue Se;
    BiTNode *p = T;
    enQueue(Se, p);
    while (!isEmptySe(Se)){
        deQueue(Se, p);
        visit(p);
        if(p->lchild) enQueue(Se, p->lchild);
        if(p->rchild) enQueue(Se, p->rchild);
    }
}

1-2 构建二叉树 (根据俩数组构建)

1-2-1先序-中序

1-2-2后序-中序

1-2-3层序-中序


1-3 翻转二叉树

翻转 递归 迭代
- 将 temp 结点作为中间变量, 交换左右; 先序递归遍历
/*法一: 递归思想--先序递归交换左右*/
//*法一: 递归思想*/  
//将 temp 结点作为中间变量, 交换左右; 先序递归遍历
BiTree invertBTree_N(BiTNode *&root) {
  if (!root)
    return nullptr;
  BiTNode *temp = root->rchild;
  root->rchild = root->lchild;
  root->lchild = temp;
  invertBTree_N(root->lchild);
  invertBTree_N(root->rchild);
  return root;
}
/*法三: 静态转置-- 层序遍历交换*/
/*法三: 静态转置 -- 层序遍历交换*/
// 队列 - 迭代法 -- 层序
BiTree invertBTree_Se(BiTNode *&root) {
  SeQueue Se;
  if (root)
    enQueue(Se, root);
  while (!isEmptySe(Se)) {
    BiTNode *curr, *temp;
    deQueue(Se, curr);
    // swap l r
    temp = curr->lchild;
    curr->lchild = curr->rchild;
    curr->rchild = temp;
    if (curr->lchild)
      enQueue(Se, curr->lchild);
    if (curr->rchild)
      enQueue(Se, curr->rchild);
  }
  return root;
}
// ***栈 - 迭代法 --深度DFS
// 栈 - 迭代法  --深度DFS
BiTree invertBTree_Sq(BiTNode *&root) {
  if (!root)
    return nullptr;
  SqStack Sq;
  initStack(Sq);
  Push(Sq, root);
  while (!isEmptySq(Sq)) {
    BiTree curr;
    Pop(Sq, curr);
    BiTree temp = curr->lchild; // swap
    curr->lchild = curr->rchild;
    curr->rchild = temp;

    if (curr->rchild)
      Push(Sq, curr->rchild);
    if (curr->lchild)
      Push(Sq, curr->lchild);
  }
  return root;
}

1-4 对称二叉树

  1. 思想
    终止条件:
  • 左节点为空,右节点不为空,不对称,return false
  • 左不为空,右为空,不对称 return false
  • 左右都为空,对称,返回true
  • 左右都不为空,比较节点数值,不相同就return false
  1. 代码
2.1. 递归
bool compare(BiTNode* left, BiTNode* right) {
    if(left == NULL && right == NULL)   return true;
    else if(left == NULL && right != NULL)  return false;
    else if(left != NULL && right == NULL) return false;
    else if(left->data != right->data)    return false;
    //else    return true;
    bool outside = compare(left->lchild, right->rchild); // 返回左的左,右的右
    bool inside = compare(left->rchild, right->lchild);  // 返回左的右,右的左
    bool isSame = outside && inside;
    return isSame;
    //else return compare(left->lchild, right->rchild) 
    //&& compare(left->rchild, right->lchild);
    }
2.2. 迭代
// 法二 : 迭代
bool isSymmetric(BiTree root) {
  if (root == NULL)
    return true;
  // 左右子树入队列
  SeQueue Se;
  BiTNode *leftNode, *rightNode;
  enQueue(Se, root->lchild);
  enQueue(Se, root->rchild);
  while (!isEmptySe(Se)) { // 判断两棵树是否相互对称
    deQueue(Se, leftNode);
    deQueue(Se, rightNode);
    // 左右结点同时为空,继续判断
    if (!leftNode && !rightNode)
      continue;
    // 左右至少一个不为空,或左右data域不相等
    if ((!leftNode || !rightNode || (leftNode->data != rightNode->data)))
      return false;
    //入队列 左的左, 右的右; 左的右, 右的左
    enQueue(Se, leftNode->lchild);
    enQueue(Se, rightNode->rchild);
    enQueue(Se, leftNode->rchild);
    enQueue(Se, rightNode->lchild);
  }
  return true;
}

标签:lchild,遍历,curr,Sq,对称,rchild,root,Se,翻转
来源: https://www.cnblogs.com/moHyio-YOLO/p/1shu.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有