📜  二叉树中的成对交换叶节点

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

二叉树中的成对交换叶节点

给定一棵二叉树,我们需要编写一个程序来从左到右成对交换给定二叉树中的叶节点,如下所示。

交换前的树:

交换后的树:


原始二叉树的叶子节点从左到右的顺序是(4, 6, 7, 9, 10)。现在,如果我们尝试从这个序列中形成对,我们将有两个对,即 (4, 6), (7, 9)。最后一个节点 (10) 无法与任何节点形成对,因此未交换。

解决这个问题的思路是先从左到右遍历二叉树的叶子节点。
在遍历叶子节点时,我们维护两个指针来跟踪一对中的第一个和第二个叶子节点和一个变量count来跟踪遍历的叶子节点的计数。
现在,如果我们仔细观察就会发现,在遍历的过程中,如果遍历的叶子节点数是偶数,则意味着我们可以形成一对叶子节点。为了跟踪这对,我们使用上面提到的两个指针firstPtrsecondPtr 。每次遇到叶节点时,我们都会用这个叶节点初始化secondPtr 。现在如果计数是奇数,我们用secondPtr初始化firstPtr ,否则我们只是交换这两个节点。

以下是上述想法的 C++ 实现:

/* C++ program to pairwise swap
   leaf nodes from left to right */
#include 
using namespace std;
  
// A Binary Tree Node
struct Node
{
    int data;
    struct Node *left, *right;
};
  
// function to swap two Node
void Swap(Node **a, Node **b)
{
    Node * temp = *a;
    *a = *b;
    *b = temp;
}
  
// two pointers to keep track of
// first and second nodes in a pair
Node **firstPtr;
Node **secondPtr;
  
// function to pairwise swap leaf
// nodes from left to right
void pairwiseSwap(Node **root, int &count)
{
    // if node is null, return
    if (!(*root))
        return;
  
    // if node is leaf node, increment count
    if(!(*root)->left&&!(*root)->right)
    {
        // initialize second pointer
        // by current node
        secondPtr  = root;
  
        // increment count
        count++;
  
        // if count is even, swap first
        // and second pointers
        if (count%2 == 0)
            Swap(firstPtr, secondPtr);
  
        else
  
            // if count is odd, initialize
            // first pointer by second pointer
            firstPtr  = secondPtr;
    }
  
    // if left child exists, check for leaf
    // recursively
    if ((*root)->left)
        pairwiseSwap(&(*root)->left, count);
  
    // if right child exists, check for leaf
    // recursively
    if ((*root)->right)
        pairwiseSwap(&(*root)->right, count);
  
}
  
// Utility function to create a new tree node
Node* newNode(int data)
{
    Node *temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// function to print inorder traversal
// of binary tree
void printInorder(Node* node)
{
    if (node == NULL)
        return;
  
    /* first recur on left child */
    printInorder(node->left);
  
    /* then print the data of node */
    printf("%d ", node->data);
  
    /* now recur on right child */
    printInorder(node->right);
}
  
// Driver program to test above functions
int main()
{
    // Let us create binary tree shown in
    // above diagram
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->right->left = newNode(5);
    root->right->right = newNode(8);
    root->right->left->left = newNode(6);
    root->right->left->right = newNode(7);
    root->right->right->left = newNode(9);
    root->right->right->right = newNode(10);
  
    // print inorder traversal before swapping
    cout << "Inorder traversal before swap:\n";
    printInorder(root);
    cout << "\n";
  
    // variable to keep track
    // of leafs traversed
    int c = 0;
  
    // Pairwise swap of leaf nodes
    pairwiseSwap(&root, c);
  
    // print inorder traversal after swapping
    cout << "Inorder traversal after swap:\n";
    printInorder(root);
    cout << "\n";
  
    return 0;
}

输出:

Inorder traversal before swap:
4 2 1 6 5 7 3 9 8 10 
Inorder traversal after swap:
6 2 1 4 5 9 3 7 8 10