📜  展平二叉搜索树以仅将树转换为波形列表

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

展平二叉搜索树以仅将树转换为波形列表

给定一个由N个不同节点组成的二叉搜索树,任务是将给定的二叉搜索树展平以将树转换为波列表。如果arr[0] >= arr[1] <= arr[2] >= arr[3] <= arr[4] >= ... ,则波形列表arr[0..n-1]称为波形列表。

例子:

方法:给定问题可以通过观察二叉搜索树的中序遍历以非递减顺序给出节点来解决。因此,将给定树的前N/2和最后N/2个节点的中序遍历分别使用树的迭代中序遍历和树的中序遍历的逆序存储在两个堆栈S1S2中堆栈中节点的指针以获取Wave List 。在这些步骤之后,将树的所有左指针设为NULL以使其变平。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Tree Node Structure
struct TreeNode {
 
    int data;
    TreeNode* right;
    TreeNode* left;
 
    // Constructor
    TreeNode(int data)
    {
        this->data = data;
        this->left = NULL;
        this->right = NULL;
    }
};
 
// Function to insert nodes in the
// binary tree
TreeNode* insertNode(int data,
                     TreeNode* root)
{
    if (root == NULL) {
        TreeNode* node
            = new TreeNode(data);
        return node;
    }
    else if (data > root->data) {
        root->right = insertNode(
            data, root->right);
    }
    else if (data <= root->data) {
        root->left = insertNode(
            data, root->left);
    }
 
    // Return the root node
    return root;
}
 
// Function to count number of nodes
int countNodes(TreeNode* root)
{
    if (root == NULL)
        return 0;
 
    else
        return countNodes(root->left)
               + countNodes(root->right) + 1;
}
 
// Function to create an array
// to wave array
TreeNode* toWaveList(TreeNode* root)
{
    int count = countNodes(root);
    vector ans;
 
    // For inorder traversal
    stack s1;
 
    // For reverse Inorder traversal
    stack s2;
 
    TreeNode *root1 = root, *root2 = root;
    TreeNode *curr1 = NULL, *curr2 = NULL;
 
    // To store the root pointer of tree
    // after flattening
    TreeNode* head = NULL;
 
    // Flatten the tree
    TreeNode* temp = NULL;
 
    int l = 0;
    while (l++ < ceil(count / 2.0)) {
 
        // Iterative inorder traversal
        while (root1) {
            s1.push(root1);
            root1 = root1->left;
        }
        curr1 = s1.top();
        s1.pop();
        root1 = curr1->right;
 
        // Iterative reverse inorder
        // traversal
        while (root2) {
            s2.push(root2);
            root2 = root2->right;
        }
        curr2 = s2.top();
        s2.pop();
        root2 = curr2->left;
 
        // Condition for handling situation
        // where both curr1 and curr2 points
        // to the same data
        if (curr1->data == curr2->data) {
            temp->right = curr1;
            temp = temp->right;
            break;
        }
 
        // Flattening the tree
        if (head == NULL) {
            head = curr1;
            temp = curr1;
 
            temp->right = curr2;
 
            // temp->left = NULL
            temp = temp->right;
        }
        else {
 
            temp->right = curr1;
            temp = temp->right;
 
            temp->right = curr2;
            temp = temp->right;
        }
    }
    temp->right = NULL;
 
    // Setting all the left pointers
    // to NULL
    temp = head;
    while (temp) {
        temp->left = NULL;
        temp = temp->right;
    }
 
    return head;
}
 
// Driver Code
int main()
{
    TreeNode* root = NULL;
    int tree[] = { 1, 0, 10 };
    for (int i = 0; i < 3; i++) {
        root = insertNode(tree[i], root);
    }
 
    // Function Call
    TreeNode* head = toWaveList(root);
    while (head) {
        cout << head->data << " ";
        head = head->right;
    }
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG{
 
// Tree Node Structure
static class TreeNode {
 
    int data;
    TreeNode right;
    TreeNode left;
 
    // Constructor
    TreeNode(int data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
};
 
// Function to insert nodes in the
// binary tree
static TreeNode insertNode(int data,
                     TreeNode root)
{
    if (root == null) {
        TreeNode node
            = new TreeNode(data);
        return node;
    }
    else if (data > root.data) {
        root.right = insertNode(
            data, root.right);
    }
    else if (data <= root.data) {
        root.left = insertNode(
            data, root.left);
    }
 
    // Return the root node
    return root;
}
 
// Function to count number of nodes
static int countNodes(TreeNode root)
{
    if (root == null)
    return 0;
 
    else
        return countNodes(root.left)
               + countNodes(root.right) + 1;
}
 
// Function to create an array
// to wave array
static TreeNode toWaveList(TreeNode root)
{
    int count = countNodes(root);
    Vector ans = new Vector<>();
 
    // For inorder traversal
    Stack s1 = new Stack<>();
 
    // For reverse Inorder traversal
    Stack s2 = new Stack<>();
 
    TreeNode root1 = root, root2 = root;
    TreeNode curr1 = null, curr2 = null;
 
    // To store the root pointer of tree
    // after flattening
    TreeNode head = null;
 
    // Flatten the tree
    TreeNode temp = null;
 
    int l = 0;
    while (l++ < Math.ceil(count / 2.0)) {
 
        // Iterative inorder traversal
        while (root1 != null) {
            s1.add(root1);
            root1 = root1.left;
        }
        curr1 = s1.peek();
        s1.pop();
        root1 = curr1.right;
 
        // Iterative reverse inorder
        // traversal
        while (root2 != null) {
            s2.add(root2);
            root2 = root2.right;
        }
        curr2 = s2.peek();
        s2.pop();
        root2 = curr2.left;
 
        // Condition for handling situation
        // where both curr1 and curr2 points
        // to the same data
        if (curr1.data == curr2.data) {
            temp.right = curr1;
            temp = temp.right;
            break;
        }
 
        // Flattening the tree
        if (head == null) {
            head = curr1;
            temp = curr1;
 
            temp.right = curr2;
 
            // temp.left = null
            temp = temp.right;
        }
        else {
 
            temp.right = curr1;
            temp = temp.right;
 
            temp.right = curr2;
            temp = temp.right;
        }
    }
    temp.right = null;
 
    // Setting all the left pointers
    // to null
    temp = head;
    while (temp!=null) {
        temp.left = null;
        temp = temp.right;
    }
 
    return head;
}
 
// Driver Code
public static void main(String[] args)
{
    TreeNode root = null;
    int tree[] = { 1, 0, 10 };
    for (int i = 0; i < 3; i++) {
        root = insertNode(tree[i], root);
    }
 
    // Function Call
    TreeNode head = toWaveList(root);
    while (head!=null) {
        System.out.print(head.data+ " ");
        head = head.right;
    }
 
}
}
 
// This code is contributed by gauravrajput1


Javascript


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Tree Node Structure
  public    class TreeNode {
 
    public    int data;
    public    TreeNode right;
    public    TreeNode left;
 
    // Constructor
    public    TreeNode(int data) {
      this.data = data;
      this.left = null;
      this.right = null;
    }
  };
 
  // Function to insert nodes in the
  // binary tree
  static TreeNode insertNode(int data, TreeNode root) {
    if (root == null) {
      TreeNode node = new TreeNode(data);
      return node;
    } else if (data > root.data) {
      root.right = insertNode(data, root.right);
    } else if (data <= root.data) {
      root.left = insertNode(data, root.left);
    }
 
    // Return the root node
    return root;
  }
 
  // Function to count number of nodes
  static int countNodes(TreeNode root) {
    if (root == null)
      return 0;
 
    else
      return countNodes(root.left) + countNodes(root.right) + 1;
  }
 
  // Function to create an array
  // to wave array
  static TreeNode toWaveList(TreeNode root) {
    int count = countNodes(root);
    List ans = new List();
 
    // For inorder traversal
    Stack s1 = new Stack();
 
    // For reverse Inorder traversal
    Stack s2 = new Stack();
 
    TreeNode root1 = root, root2 = root;
    TreeNode curr1 = null, curr2 = null;
 
    // To store the root pointer of tree
    // after flattening
    TreeNode head = null;
 
    // Flatten the tree
    TreeNode temp = null;
 
    int l = 0;
    while (l++ < Math.Ceiling(count / 2.0)) {
 
      // Iterative inorder traversal
      while (root1 != null) {
        s1.Push(root1);
        root1 = root1.left;
      }
      curr1 = s1.Peek();
      s1.Pop();
      root1 = curr1.right;
 
      // Iterative reverse inorder
      // traversal
      while (root2 != null) {
        s2.Push(root2);
        root2 = root2.right;
      }
      curr2 = s2.Peek();
      s2.Pop();
      root2 = curr2.left;
 
      // Condition for handling situation
      // where both curr1 and curr2 points
      // to the same data
      if (curr1.data == curr2.data) {
        temp.right = curr1;
        temp = temp.right;
        break;
      }
 
      // Flattening the tree
      if (head == null) {
        head = curr1;
        temp = curr1;
 
        temp.right = curr2;
 
        // temp.left = null
        temp = temp.right;
      } else {
 
        temp.right = curr1;
        temp = temp.right;
 
        temp.right = curr2;
        temp = temp.right;
      }
    }
    temp.right = null;
 
    // Setting all the left pointers
    // to null
    temp = head;
    while (temp != null) {
      temp.left = null;
      temp = temp.right;
    }
 
    return head;
  }
 
  // Driver Code
  public static void Main(String[] args) {
    TreeNode root = null;
    int []tree = { 1, 0, 10 };
    for (int i = 0; i < 3; i++) {
      root = insertNode(tree[i], root);
    }
 
    // Function Call
    TreeNode head = toWaveList(root);
    while (head != null) {
      Console.Write(head.data + " ");
      head = head.right;
    }
 
  }
}
 
// This code is contributed by gauravrajput1


输出:
0 10 1

时间复杂度: O(N)
辅助空间: O(H),其中 H 是BST 的高度