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, ''))