二叉树数组到有序二进制树数组

时间:2018-01-16 15:35:09

标签: java binary-tree binary-search-tree inorder

我正在解决HackerEarth问题之一。问题陈述如下,

给定一个包含N个节点的完整二叉树,并且每个节点都附加了一个不同的整数 ai ,找到可以将二进制树转换为二叉树搜索树的最小交换次数。在一次交换中,您可以选择任意两个节点并交换它们的值。

您将获得二叉树的数组表示。树的根将位于 a [1] root的左子节点将位于 a [2] ,root的右子节点将位于a3处。阵列位置 k 处的节点的左子节点将位于 a [2 * k] 处,并且阵列位置k处的节点的右子节点将位于 a [2 *] K + 1]

问题是如何将给定数组转换为树的有序数组。我尝试了下面的代码。在网上我找不到任何链接。

static void inOrderArr(int destIndex,int index, int[] source, int[] dest) {
    int leftIndex = (index ) * 2;
    int rightIndex = (((index ) * 2) + 1);

    if(leftIndex<source.length){
        inOrderArr(destIndex,leftIndex, source,dest);
    }
    System.out.println(index);
    dest[destIndex++] = source[index-1];
    if(rightIndex<source.length){
        inOrderArr(destIndex,rightIndex, source,dest);
    }

}

2 个答案:

答案 0 :(得分:0)

试试这个!

这个想法是使用二进制搜索树的顺序遍历按其值的递增顺序这一事实。因此,找到二进制树的inorder遍历并将其存储在数组中并尝试对数组进行排序。

这是c中的代码,用于将给定数组转换为树的有序数组。

#include<stdio.h>
#include<stdlib.h>
#define bool int

/* A binary tree tNode has data, pointer to left child
   and a pointer to right child */
struct tNode
{
   int data;
   struct tNode* left;
   struct tNode* right;
};

/* Structure of a stack node. Linked List implementation is used for 
   stack. A stack node contains a pointer to tree node and a pointer to 
   next stack node */
struct sNode
{
  struct tNode *t;
  struct sNode *next;
};

/* Stack related functions */
void push(struct sNode** top_ref, struct tNode *t);
struct tNode *pop(struct sNode** top_ref);
bool isEmpty(struct sNode *top);

/* Iterative function for inorder tree traversal */
void inOrder(struct tNode *root)
{
  /* set current to root of binary tree */
  struct tNode *current = root;
  struct sNode *s = NULL;  /* Initialize stack s */
  bool done = 0;

  while (!done)
  {
    /* Reach the left most tNode of the current tNode */
    if(current !=  NULL)
    {
      /* place pointer to a tree node on the stack before traversing 
        the node's left subtree */
      push(&s, current);                                               
      current = current->left;  
    }

    /* backtrack from the empty subtree and visit the tNode 
       at the top of the stack; however, if the stack is empty,
      you are done */
    else                                                             
    {
      if (!isEmpty(s))
      {
        current = pop(&s);
        printf("%d ", current->data);

        /* we have visited the node and its left subtree.
          Now, it's right subtree's turn */
        current = current->right;
      }
      else
        done = 1; 
    }
  } /* end of while */ 
}     

/* UTILITY FUNCTIONS */
/* Function to push an item to sNode*/
void push(struct sNode** top_ref, struct tNode *t)
{
  /* allocate tNode */
  struct sNode* new_tNode =
            (struct sNode*) malloc(sizeof(struct sNode));

  if(new_tNode == NULL)
  {
     printf("Stack Overflow \n");
     getchar();
     exit(0);
  }            

  /* put in the data  */
  new_tNode->t  = t;

  /* link the old list off the new tNode */
  new_tNode->next = (*top_ref);   

  /* move the head to point to the new tNode */
  (*top_ref)    = new_tNode;
}

/* The function returns true if stack is empty, otherwise false */
bool isEmpty(struct sNode *top)
{
   return (top == NULL)? 1 : 0;
}   

/* Function to pop an item from stack*/
struct tNode *pop(struct sNode** top_ref)
{
  struct tNode *res;
  struct sNode *top;

  /*If sNode is empty then error */
  if(isEmpty(*top_ref))
  {
     printf("Stack Underflow \n");
     getchar();
     exit(0);
  }
  else
  {
     top = *top_ref;
     res = top->t;
     *top_ref = top->next;
     free(top);
     return res;
  }
}

/* Helper function that allocates a new tNode with the
   given data and NULL left and right pointers. */
struct tNode* newtNode(int data)
{
  struct tNode* tNode = (struct tNode*)
                       malloc(sizeof(struct tNode));
  tNode->data = data;
  tNode->left = NULL;
  tNode->right = NULL;

  return(tNode);
}

/* Driver program to test above functions*/
int main()
{

  struct tNode *root = newtNode(5);
  root->left        = newtNode(6);
  root->right       = newtNode(7);
  root->left->left  = newtNode(8);
  root->left->right = newtNode(9);
  root->right->left = newtNode(10);
  root->right->right= newtNode(11);

  inOrder(root);

  getchar();
  return 0;
}

答案 1 :(得分:0)

我尝试了以下解决方案并且有效。

private static void inorderTraversal(int array[], int pos, Node[] nodes) {
    if (pos >= array.length) {
        return;
    }
    inorderTraversal(array, 2 * pos + 1, nodes);
    nodes[Node.count] = new Node(array[pos], Node.count);
    Node.count++;
    inorderTraversal(array, 2 * pos + 2, nodes);
}

这是节点类型声明

static private class Node implements Comparable<Node> {

    private static int count = 0;

    public Node(int value) {
        this.value = value;
    }

    public Node(int value, int position) {
        this(value);
        this.position = position;
    }

    private int value;
    private int position;
    private boolean visited;

    public boolean isVisited() {
        return visited;
    }

    public void markVisited() {
        visited = true;
    }

    @Override
    public int compareTo(Node o) {
        if (this.value >= o.value) {
            return 1;
        }
        return -1;
    }
}