1

I need some help in this data structure homework problem. I was requested to write an algorithm that creates an AVL tree from a sorted array in O(n) time. I read this solution method: Creating a Binary Search Tree from a sorted array

They do it recursively for the two halves of the sorted array and it works.

I found a different solution and I want to check if it's valid.

My solution is to store another property of the root called "root.minimum" that will contain a pointer to the minimum.

Then, for the k'th element, we'll add it recursively to the AVL tree of the previous k-1 elements. We know that the k'th element is smaller than the minimum, so we'll add it to the left of root.minimum to create the new tree. Now the tree is no longer balanced, but all we need to do to fix it is just one right rotation of the previous minimum.

This way the insertion takes O(1) for every node, and in total O(n).

Is this method valid to solve the problem?

Edit: I meant that I"m starting from the largest element. And then continue adding the rest according to the order. So each element I'm adding is smaller than the rest of them so I add it to the left of root.minimum. Then all I have to do to balance the tree is a right rotation which is O(1). Is this a correct solution?

PhysicsPrincess
  • 342
  • 1
  • 10

1 Answers1

1

If you pick a random element as the root in the first place (which is probably not the best idea, since we know the root should be the middle element), you put root itself in the root.minimum. Then for each new element, if it is smaller than root.minimum, you do as you said and make the tree balanced in O(1) time. But what if it is larger? In that case we need to compare it with the root.minimum of the right child, and if it is also larger, with the root.minimum of the right child of the right child and so on. This might take O(k) in the worst case, which will result in O(n^2) in the end. Also, this way, you are not using the sorted property of the array.

Hadi GhahremanNezhad
  • 2,377
  • 5
  • 29
  • 58
  • If I choose the maximum element first as the root and then go down with the rest of the sorted elements. (In a non-increasing array I start with the first, then the second etc..) In this case the next element inserted is always smaller and then only one rotation is needed. Is that valid now? – PhysicsPrincess Aug 16 '19 at 22:42
  • No, because when you add the new element to the tree, you don't have to compare it with all elements (since you have the pointer). However, the tree becomes unbalanced, and needs **more than one** rotations to become balanced. In fact, with this approach, you will need `log(h)` rotations at each insertion which makes the whole complexity `O(nlogn)`. You can try with this array to see my point: `[7,6,5,4,3,2,1]`. – Hadi GhahremanNezhad Aug 17 '19 at 15:49
  • Why do I need more than one rotation? I mean, in general when inserting a new element to an AVL tree we need to balance the subtree of the first unbalanced ancestor. This happens always in a constant number of operations - one rotation, theta(1). Same goes with this example, in every insertion you to rotate once or 0 times.. – PhysicsPrincess Aug 18 '19 at 12:06
  • Reference to the fact that only a constant number of rotations need to balance an AVL tree after insertion: https://www.google.com/amp/s/www.geeksforgeeks.org/avl-tree-set-1-insertion/amp/ – PhysicsPrincess Aug 18 '19 at 12:10
  • According to the link you put here, "***the time complexity of AVL insert remains same as BST insert which is O(h) where h is the height of the tree***". In this case, since each new element goes to the bottom left of the tree. The first unbalanced sub-tree is not just the `root.minimum`; it is the left child of the whole tree and needs more than one rotation to become balanced. – Hadi GhahremanNezhad Aug 19 '19 at 13:12