剑指offer

Posted cherry-bail

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer相关的知识,希望对你有一定的参考价值。

##本期 判断树的子结构 && 树的镜像

#题目 判断树的子结构

给两个二叉树,判断后一颗是否是前一颗的子树

方法:判断二叉树的树根和子树的树根是否相同,

      若相同则继续判断左右孩子;

      若不相同则二叉树的左右孩子作为树根继续做出上述的比较。

public boolean hasSubTree(treeNode root1, TreeNode root2){

  if(root1 == null || root2 == null)  return false;

  return isSubTree(root1, root2) || hasSubTree(root1.leftchild, root2) || hasSubTree(root1.rightchild, root2);

}

public boolean isSubTree(TreeNode root1, TreeNode root2){

  if(root2 == null)  return true;

  if(root1 == null)  return false;

  if(root1.val == root2.val){

    return(isSubTree(root1.leftchild, root2.leftchild) && isSubTree(root1.rightchild, root2.rightchild));

  }else{

    return false;

  }

}

 

题目 操作给定的二叉树,将其变换为源二叉树的镜像

源二叉树    8                  镜像二叉树    8

                  /                                        / 

                6    10                              10      6

               /      /                               /        /

             5   7  9  11                       11  9   7   5

如上图中的两颗树结构看出,镜像就是反转了所有节点的左右孩子。

那我们可以有递归和非递归的方式,将所有树节点的左右孩子交换

#递归

public void mirrorTrans(TreeNode root){

  if(root == null)  return;

  if(root.leftchild = null && root.rightchild == null)  return;

  TreeNode temp = root.leftchild;

  root.leftchild = root.rightchild;

  root.rightchild = temp;

  if(root.leftchild != null)  mirrorTrans(root.leftchild);

  if(root.rightchild != null)  mirrorTrans(root.rightchild);

}

#前序遍历

前序遍历的顺序是根左右,我们按照顺序将所有左节点的左右孩子交换位置,依次压栈,出栈的时候将所有右节点的左右孩子交换位置

public void pre(TreeNode root){

  if(root == null)  return;

  Stack nstack;

  TreeNode temp;

  while(root != null || nstack.empty() != true){

    while(root != null){

      if(root.leftchild != null && root.rightchild != null){

        TreeNode temp = root.leftchild;

        root.leftchild = root.rightchild;

        root.rightchild = temp;

      }

      nstack.push(root);

      root = root.leftchild;

    }

    while(nstack.empty() != true){

      root = nstack.top;

      nstack.pop();

      root = root.rightchild;

    }

  }

}

 

public void preBFS(TreeNode root){

  if(root == null)  return;

  Stack nstack;

  TreeNode temp;

  nstack.push(root);

  while(nstack.empty() != true){

    root = nstack.top;

    nstack.pop();

  }

    if(root.leftchild != null && root.rightchild != null){

      TreeNode temp = root.leftchild;

      root.leftchild = root.rightchild;

      root.rightchild = temp;

    }

    if(root.leftchild != null){

      nstack.push(root.leftchild);

    }

    if(root.rightchild != null){

      nstack.push(root.rightchild);

    }

  }

}

 

#中序遍历

中序遍历的顺序是左根右

由于遍历左节点后,

public void mid(TreeNode root){

  if(root == null)  return;

  Stack nstack;

  TreeNode temp;

  while(root != null || nstack.empty() != true){

    while(root != null){

      nstack.push(root);

      root = root.leftchild;

    }

    if(nstack.empty() != true){

      root = nstack.top;

      if(root.leftchild != null && root.rightchild != null){

        TreeNode temp = root.leftchild;

        root.leftchild = root.rightchild;

        root.rightchild = temp;

      } 

      nstack.pop();

      root = root.leftchild;

    }

  }

}

 #后序遍历

后续遍历的顺序是左右根,同先序遍历

public void post(TreeNode root){

  if(root == null)  return;

  TreeNode cur;  //当前节点

  TreeNode pre == null;  //前一次访问的节点

  nstack.push(root);

  while(nstack.empty( ) != true){

    cur = nstack.top;

    if((cur.leftchild == null || cur.rightchild == null) || (pre != null &&(pre == cur.leftchild || pre == cur.rightchild))){

    //如果当前结点没有孩子结点或者孩子节点都已被访问过

    // 将原来的输出改为交换左右子树即可

      if(cur.leftchild != null && cur.rightchild != null){

        TreeNode temp = root.leftchild;

        root.leftchild = root.rightchild;

        root.rightchild = temp;

      }

      nstack.pop();

      pre = cur;

    }else{

      // 由于栈是先进后出,因此先入右孩子, 再左孩子可以保证递归返回时先遍历左孩子

      if(cur.rightchild != NULL){

        nstack.push(cur.rightchild);

      }

      if(cur.leftchild != NULL){

        nstack.push(cur.leftchild);

      }

    }

  }

}

以上是关于剑指offer的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 45. 把数组排成最小的数 剑指 Offer 61. 扑克牌中的顺子 剑指 Offer 40. 最小的k个数

剑指Offer数据结构

剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)

剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)

刷题记录leetcode 剑指 Offer(第 2 版)03-11

剑指offer第二版和专项突击版有啥区别