Algorithm 二叉树的镜像

Algorithm 二叉树的镜像,algorithm,data-structures,Algorithm,Data Structures,假设有一棵树: 1 / \ 2 3 / \ 4 5 然后镜像将为: 1 / \ 3 2 / \ 5 4 假设节点属于此结构: struct node{ node left; node right;

假设有一棵树:

             1
            / \
           2   3
              / \
             4   5
然后镜像将为:

              1
             / \
            3   2
           / \
          5   4
假设节点属于此结构:

struct node{
      node left;
      node right;
      int value;
}
有人能为这个提出一个算法吗?

听起来像是家庭作业

看起来很容易。编写一个递归例程,深度优先访问每个节点,并构建镜像树,左右颠倒

struct node *mirror(struct node *here) {

  if (here == NULL)
     return NULL;
  else {

    struct node *newNode = malloc (sizeof(struct node));

    newNode->value = here->value;
    newNode->left = mirror(here->right);
    newNode->right = mirror(here->left);

    return newNode;
  }
}
这将返回一个新的树-其他一些答案在适当的位置执行此操作。取决于你的作业要求你做什么:)

平庸的解决方案:

for each node in tree
    exchange leftchild with rightchild.
public void mirrorIterative() {
    Queue<TreeNode> nodeQ = new LinkedList<TreeNode>();
    nodeQ.add(root);
    while(!nodeQ.isEmpty()) {
        TreeNode node = nodeQ.remove();
        if(node.leftChild == null && node.rightChild == null)
            continue;
        if(node.leftChild != null && node.rightChild != null) {
            TreeNode temp = node.leftChild;
            node.leftChild = node.rightChild;
            node.rightChild = temp;
            nodeQ.add(node.leftChild);
            nodeQ.add(node.rightChild);
        }
        else if(node.leftChild == null) {
            node.leftChild = node.rightChild;
            node.rightChild = null;
            nodeQ.add(node.leftChild);
        } else {
            node.rightChild = node.leftChild;
            node.leftChild = null;
            nodeQ.add(node.rightChild);
        }
    }
}
void镜像(节点*&root2,节点*根)
{
if(root==NULL)
{
root2=NULL;
}
否则{
root2=新节点;
root2->data=root->data;
root2->left=NULL;
root2->right=NULL;
镜像(根2->左,根->右);
镜像(根2->右,根->左);
}
}

这是我的函数。如果有更好的解决方案,请建议:

for each node in tree
    exchange leftchild with rightchild.
public void mirrorIterative() {
    Queue<TreeNode> nodeQ = new LinkedList<TreeNode>();
    nodeQ.add(root);
    while(!nodeQ.isEmpty()) {
        TreeNode node = nodeQ.remove();
        if(node.leftChild == null && node.rightChild == null)
            continue;
        if(node.leftChild != null && node.rightChild != null) {
            TreeNode temp = node.leftChild;
            node.leftChild = node.rightChild;
            node.rightChild = temp;
            nodeQ.add(node.leftChild);
            nodeQ.add(node.rightChild);
        }
        else if(node.leftChild == null) {
            node.leftChild = node.rightChild;
            node.rightChild = null;
            nodeQ.add(node.leftChild);
        } else {
            node.rightChild = node.leftChild;
            node.leftChild = null;
            nodeQ.add(node.rightChild);
        }
    }
}
无效镜像(结构节点*p)
{
结构节点*q;
如果(p!=NULL)
{
q=掉期交易记录(p&p);
p=q;
镜像(p->左);
镜像(p->右);
}
}
结构节点*swaptrs(结构节点**p)
{
结构节点*temp;
温度=(*p)->左侧;
(*p)->左=(*p)->右;
(*p)->右=温度;
返回(*p);
}
迭代解决方案:

for each node in tree
    exchange leftchild with rightchild.
public void mirrorIterative() {
    Queue<TreeNode> nodeQ = new LinkedList<TreeNode>();
    nodeQ.add(root);
    while(!nodeQ.isEmpty()) {
        TreeNode node = nodeQ.remove();
        if(node.leftChild == null && node.rightChild == null)
            continue;
        if(node.leftChild != null && node.rightChild != null) {
            TreeNode temp = node.leftChild;
            node.leftChild = node.rightChild;
            node.rightChild = temp;
            nodeQ.add(node.leftChild);
            nodeQ.add(node.rightChild);
        }
        else if(node.leftChild == null) {
            node.leftChild = node.rightChild;
            node.rightChild = null;
            nodeQ.add(node.leftChild);
        } else {
            node.rightChild = node.leftChild;
            node.leftChild = null;
            nodeQ.add(node.rightChild);
        }
    }
}
public void mirror(){
Queue nodeQ=new LinkedList();
nodeQ.add(根);
而(!nodeQ.isEmpty()){
TreeNode node=nodeQ.remove();
if(node.leftChild==null&&node.righchild==null)
继续;
if(node.leftChild!=null&&node.rightChild!=null){
TreeNode temp=node.leftChild;
node.leftChild=node.rightChild;
node.rightChild=temp;
nodeQ.add(node.leftChild);
nodeQ.add(node.rightChild);
}
else if(node.leftChild==null){
node.leftChild=node.rightChild;
node.rightChild=null;
nodeQ.add(node.leftChild);
}否则{
node.rightChild=node.leftChild;
node.leftChild=null;
nodeQ.add(node.rightChild);
}
}
}
递归Java代码

public class TreeMirrorImageCreator {

public static Node createMirrorImage(Node originalNode,Node mirroredNode){

    mirroredNode.setValue(originalNode.getValue());

    if(originalNode.getLeft() != null){
        mirroredNode.setLeft(createMirrorImage(originalNode.getRight(),new Node(0)));
    }

    if(originalNode.getRight() != null){
        mirroredNode.setRight(createMirrorImage(originalNode.getLeft(), new Node(0)));
    }

    return mirroredNode;

}
}
时间复杂度:O(n)
空间复杂性:O(n)

JAVA中的递归和迭代方法: 1) 递归:

    public static TreeNode mirrorBinaryTree(TreeNode root){

    if(root == null || (root.left == null && root.right == null))
        return root;

    TreeNode temp = root.left;
    root.left = root.right;
    root.right = temp;

    mirrorBinaryTree(root.left);
    mirrorBinaryTree(root.right);


    return root;

}
2) 迭代:

public static TreeNode mirrorBinaryTreeIterative(TreeNode root){
    if(root == null || (root.left == null && root.right == null))
        return root;

    TreeNode parent = root;
    Stack<TreeNode> treeStack = new Stack<TreeNode>();
    treeStack.push(root);

    while(!treeStack.empty()){
        parent = treeStack.pop();

        TreeNode temp = parent.right;
        parent.right = parent.left;
        parent.left = temp;

        if(parent.right != null)
            treeStack.push(parent.right);
        if(parent.left != null)
            treeStack.push(parent.left);
    }
    return root;
}
公共静态树节点镜像二进制树节点操作(树节点根){
if(root==null | |(root.left==null&&root.right==null))
返回根;
树节点父节点=根节点;
堆栈树堆栈=新堆栈();
推(根);
而(!treeStack.empty()){
parent=treeStack.pop();
TreeNode temp=父级。右侧;
parent.right=parent.left;
parent.left=temp;
if(parent.right!=null)
treeStack.push(父级,右侧);
if(parent.left!=null)
treeStack.push(父级,左侧);
}
返回根;
}

这个问题有很多答案。我发布了一个迭代版本,非常容易理解。它使用了级别顺序遍历

//Function for creating Binary Tree
//Assuming *root for original tree and *root2 for mirror tree
//are declared globally
void insert(int data)
{
struct treenode* temp;
if(root2 == NULL)
{
root2 = createNode(data);
return;
}
else{
queue<treenode*> q;
q.push(root2);
while(!q.empty())
{
 temp = q.front();
 q.pop();
 if(temp->left)
 q.push(temp->left);
 else{
 temp->left = createNode(data);
 return;
}
if(temp->right)
{
q.push(temp->right);
}
else{
temp -> right = createNode(data);
return;
}
}
}
}
//Iterative version for Mirror of a Binary Tree 
void mirrorBinaryTree()
{
struct treenode *front;
queue<treenode*> q;
q.push(root);
while(!q.empty())
{
 front = q.front();
 insert(front->data);
 q.pop();
 if(front->right)
 q.push(front->right);
 if(front->left)
 q.push(front->left);
}
}
//用于创建二叉树的函数
//假设原始树为*root,镜像树为*root2
//在全球范围内声明
无效插入(整型数据)
{
结构树节点*temp;
if(root2==NULL)
{
root2=createNode(数据);
返回;
}
否则{
队列q;
q、 推(root2);
而(!q.empty())
{
温度=q.前();
q、 pop();
如果(临时->左)
q、 按下(温度->左);
否则{
temp->left=createNode(数据);
返回;
}
如果(临时->右侧)
{
q、 按下(温度->右侧);
}
否则{
temp->right=createNode(数据);
返回;
}
}
}
}
//二叉树镜像的迭代版本
void mirrorBinaryTree()
{
结构树节点*前端;
队列q;
q、 推(根);
而(!q.empty())
{
front=q.front();
插入(前端->数据);
q、 pop();
如果(前->右)
q、 推(前->右);
如果(前->左)
q、 推(前->左);
}
}

这里有一种在python中使用队列的非递归方法。队列类可以这样初始化:

class Queue(object):
    def __init__(self):
        self.items = []

    def enqueue(self, item):
        self.items.insert(0, item)

    def dequeue(self):
        if not self.is_empty():
            return self.items.pop()

    def is_empty(self):
        return len(self.items) == 0

    def peek(self):
        if not self.is_empty():
            return self.items[-1]

    def __len__(self):
        return self.size()

    def size(self):
        return len(self.items)
表示节点的类:

class Node:
    def __init__(self, data):
        self.left = None
        self.right = None
        self.val = data
下面是执行此任务的方法和遍历示例:

class BinaryTree(object):
    def __init__(self, root):
        self.root = Node(root)

    def inorder(self, start, traversal):
        if start:
            traversal = self.inorder(start.left, traversal)
            traversal += f"{start.val} "
            traversal = self.inorder(start.right, traversal)
        return traversal


def mirror_tree_iterative(root):
    if root is None:
        return

    q = Queue()
    q.enqueue(root)

    while not q.is_empty():
        curr = q.peek()
        q.dequeue()
        curr.left, curr.right = curr.right, curr.left
        if curr.left:
            q.enqueue(curr.left)
        if curr.right:
            q.enqueue(curr.right)        

tree = BinaryTree(1)
tree.root.left = Node(2)
tree.root.right = Node(3)
tree.root.left.left = Node(4)
tree.root.left.right = Node(5)
tree.root.right.left = Node(6)

print(tree.inorder(tree.root, ''))
mirror_tree_iterative(tree.root)
print(tree.inorder(tree.root, ''))

它基本上是后序遍历。
class BinaryTree(object):
    def __init__(self, root):
        self.root = Node(root)

    def inorder(self, start, traversal):
        if start:
            traversal = self.inorder(start.left, traversal)
            traversal += f"{start.val} "
            traversal = self.inorder(start.right, traversal)
        return traversal


def mirror_tree_iterative(root):
    if root is None:
        return

    q = Queue()
    q.enqueue(root)

    while not q.is_empty():
        curr = q.peek()
        q.dequeue()
        curr.left, curr.right = curr.right, curr.left
        if curr.left:
            q.enqueue(curr.left)
        if curr.right:
            q.enqueue(curr.right)        

tree = BinaryTree(1)
tree.root.left = Node(2)
tree.root.right = Node(3)
tree.root.left.left = Node(4)
tree.root.left.right = Node(5)
tree.root.right.left = Node(6)

print(tree.inorder(tree.root, ''))
mirror_tree_iterative(tree.root)
print(tree.inorder(tree.root, ''))