📌  相关文章
📜  给定一棵二叉树,如何删除所有半节点?

📅  最后修改于: 2022-05-13 01:57:16.543000             🧑  作者: Mango

给定一棵二叉树,如何删除所有半节点?

给定一棵二叉树,如何删除所有半节点(只有一个子节点)?注意叶子不应该被触摸,因为它们的两个孩子都为 NULL。
例如考虑下面的树。

树1

节点 2 和 4 是半节点,因为它们的子节点之一为 Null。

这个想法是使用后序遍历来有效地解决这个问题。我们首先处理左孩子,然后是右孩子,最后是节点本身。所以我们从下往上形成新树,从叶子开始到根部。当我们处理当前节点时,它的左子树和右子树都已经被处理了。下面是这个想法的实现。

C
// C program to remove all half nodes
#include 
#include 
 
struct node
{
    int data;
    struct node* left, *right;
};
 
struct node* newNode(int data)
{
    struct node* node = (struct node*)
                        malloc(sizeof(struct node));
    node->data = data;
    node->left = node->right = NULL;
    return(node);
}
 
void printInoder(struct node*root)
{
    if (root != NULL)
    {
        printInoder(root->left);
        printf("%d ",root->data);
        printInoder(root->right);
    }
}
 
// Removes all nodes with only one child and returns
// new root (note that root may change)
struct node* RemoveHalfNodes(struct node* root)
{
    if (root==NULL)
        return NULL;
 
    root->left  = RemoveHalfNodes(root->left);
    root->right = RemoveHalfNodes(root->right);
 
    if (root->left==NULL && root->right==NULL)
        return root;
 
    /* if current nodes is a half node with left
       child NULL left, then it's right child is
       returned and replaces it in the given tree */
    if (root->left==NULL)
    {
        struct node *new_root = root->right;
        free(root); // To avoid memory leak
        return new_root;
    }
 
 
    /* if current nodes is a half node with right
       child NULL right, then it's right child is
       returned and replaces it in the given tree  */
    if (root->right==NULL)
    {
        struct node *new_root = root->left;
        free(root); // To avoid memory leak
        return new_root;
    }
 
    return root;
}
 
// Driver program
int main(void)
{
    struct node*NewRoot=NULL;
    struct node *root = newNode(2);
    root->left        = newNode(7);
    root->right       = newNode(5);
    root->left->right = newNode(6);
    root->left->right->left=newNode(1);
    root->left->right->right=newNode(11);
    root->right->right=newNode(9);
    root->right->right->left=newNode(4);
 
    printf("Inorder traversal of given tree \n");
    printInoder(root);
 
    NewRoot = RemoveHalfNodes(root);
 
    printf("\nInorder traversal of the modified tree \n");
    printInoder(NewRoot);
    return 0;
}


C++
// C++ program to remove all half nodes
#include 
using namespace std;
 
struct node
{
    int data;
    struct node* left, *right;
};
 
struct node* newNode(int data)
{
    node* nod = new node();
    nod->data = data;
    nod->left = nod->right = NULL;
    return(nod);
}
 
void printInoder(struct node*root)
{
    if (root != NULL)
    {
        printInoder(root->left);
        cout<< root->data << " ";
        printInoder(root->right);
    }
}
 
// Removes all nodes with only one child and returns
// new root (note that root may change)
struct node* RemoveHalfNodes(struct node* root)
{
    if (root==NULL)
        return NULL;
 
    root->left  = RemoveHalfNodes(root->left);
    root->right = RemoveHalfNodes(root->right);
 
    if (root->left==NULL && root->right==NULL)
        return root;
 
    /* if current nodes is a half node with left
       child NULL left, then it's right child is
       returned and replaces it in the given tree */
    if (root->left==NULL)
    {
        struct node *new_root = root->right;
        free(root); // To avoid memory leak
        return new_root;
    }
 
 
    /* if current nodes is a half node with right
       child NULL right, then it's right child is
       returned and replaces it in the given tree  */
    if (root->right==NULL)
    {
        struct node *new_root = root->left;
        free(root); // To avoid memory leak
        return new_root;
    }
 
    return root;
}
 
// Driver program
int main(void)
{
    struct node*NewRoot=NULL;
    struct node *root = newNode(2);
    root->left        = newNode(7);
    root->right       = newNode(5);
    root->left->right = newNode(6);
    root->left->right->left=newNode(1);
    root->left->right->right=newNode(11);
    root->right->right=newNode(9);
    root->right->right->left=newNode(4);
 
    cout<<"Inorder traversal of given tree \n";
    printInoder(root);
 
    NewRoot = RemoveHalfNodes(root);
 
    cout<<"\nInorder traversal of the modified tree \n";
    printInoder(NewRoot);
    return 0;
}


Java
// Java program to remove half nodes
class Node
{
    int data;
    Node left, right;
  
    Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree
{
    Node root;
  
    void printInorder(Node node)
    {
        if (node != null)
        {
            printInorder(node.left);
            System.out.print(node.data + " ");
            printInorder(node.right);
        }
    }
  
    // Removes all nodes with only one child and returns
    // new root (note that root may change)
    Node RemoveHalfNodes(Node node)
    {
        if (node == null)
            return null;
  
        node.left = RemoveHalfNodes(node.left);
        node.right = RemoveHalfNodes(node.right);
  
        if (node.left == null && node.right == null)
            return node;
  
        /* if current nodes is a half node with left
         child NULL left, then it's right child is
         returned and replaces it in the given tree */
        if (node.left == null)
        {
            Node new_root = node.right;
            return new_root;
        }
  
        /* if current nodes is a half node with right
           child NULL right, then it's right child is
           returned and replaces it in the given tree  */
        if (node.right == null)
        {
            Node new_root = node.left;
            return new_root;
        }
  
        return node;
    }
  
    // Driver program
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        Node NewRoot = null;
        tree.root = new Node(2);
        tree.root.left = new Node(7);
        tree.root.right = new Node(5);
        tree.root.left.right = new Node(6);
        tree.root.left.right.left = new Node(1);
        tree.root.left.right.right = new Node(11);
        tree.root.right.right = new Node(9);
        tree.root.right.right.left = new Node(4);
  
        System.out.println("the inorder traversal of tree is ");
        tree.printInorder(tree.root);
  
        NewRoot = tree.RemoveHalfNodes(tree.root);
  
        System.out.print("\nInorder traversal of the modified tree \n");
        tree.printInorder(NewRoot);
    }
}
 
// This code has been contributed by Mayank Jaiswal


Python3
# Python program to remove all half nodes
 
# A binary tree node
class Node:
    # Constructor for creating a new node
    def __init__(self , data):
        self.data = data
        self.left = None
        self.right = None
 
# For inorder traversal
def printInorder(root):
    if root is not None:
        printInorder(root.left)
        print (root.data,end=" ")
        printInorder(root.right)
 
# Removes all nodes with only one child and returns
# new root(note that root may change)
def RemoveHalfNodes(root):
    if root is None:
        return None
 
    # Recur to left tree
    root.left = RemoveHalfNodes(root.left)
     
    # Recur to right tree
    root.right = RemoveHalfNodes(root.right)
     
    # if both left and right child is None
    # the node is not a Half node
    if root.left is None and root.right is None:
        return root
 
    # If current nodes is a half node with left child
    # None then it's right child is returned and  
    # replaces it in the given tree
    if root.left is None:
        new_root = root.right
        temp = root
        root = None
        del(temp)
        return new_root
 
    if root.right is None:
        new_root = root.left
        temp = root
        root = None
        del(temp)
        return new_root
     
    return root
 
# Driver Program
root = Node(2)
root.left = Node(7)
root.right = Node(5)
root.left.right = Node(6)
root.left.right.left = Node(1)
root.left.right.right = Node(11)
root.right.right = Node(9)
root.right.right.left = Node(4)
 
print ("Inorder traversal of given tree")
printInorder(root)
 
NewRoot = RemoveHalfNodes(root)
 
print ("\nInorder traversal of the modified tree")
printInorder(NewRoot)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#
using System;
 
// C# program to remove half nodes
public class Node
{
    public int data;
    public Node left, right;
 
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
public class BinaryTree
{
    public Node root;
 
    public virtual void printInorder(Node node)
    {
        if (node != null)
        {
            printInorder(node.left);
            Console.Write(node.data + " ");
            printInorder(node.right);
        }
    }
 
    // Removes all nodes with only one child and returns
    // new root (note that root may change)
    public virtual Node RemoveHalfNodes(Node node)
    {
        if (node == null)
        {
            return null;
        }
 
        node.left = RemoveHalfNodes(node.left);
        node.right = RemoveHalfNodes(node.right);
 
        if (node.left == null && node.right == null)
        {
            return node;
        }
 
        /* if current nodes is a half node with left
         child NULL left, then it's right child is
         returned and replaces it in the given tree */
        if (node.left == null)
        {
            Node new_root = node.right;
            return new_root;
        }
 
        /* if current nodes is a half node with right
           child NULL right, then it's right child is
           returned and replaces it in the given tree  */
        if (node.right == null)
        {
            Node new_root = node.left;
            return new_root;
        }
 
        return node;
    }
 
    // Driver program
    public static void Main(string[] args)
    {
        BinaryTree tree = new BinaryTree();
        Node NewRoot = null;
        tree.root = new Node(2);
        tree.root.left = new Node(7);
        tree.root.right = new Node(5);
        tree.root.left.right = new Node(6);
        tree.root.left.right.left = new Node(1);
        tree.root.left.right.right = new Node(11);
        tree.root.right.right = new Node(9);
        tree.root.right.right.left = new Node(4);
 
        Console.WriteLine("the inorder traversal of tree is ");
        tree.printInorder(tree.root);
 
        NewRoot = tree.RemoveHalfNodes(tree.root);
 
        Console.Write("\nInorder traversal of the modified tree \n");
        tree.printInorder(NewRoot);
    }
}
 
  // This code is contributed by Shrikant13


Javascript
Java

script


输出:

Inorder traversal of given tree
7 1 6 11 2 5 4 9
Inorder traversal of the modified tree
1 6 11 2 4

上述解决方案的时间复杂度为 O(n),因为它对二叉树进行了简单的遍历。