why are binary heaps a tree structure? - java

Binary Heaps can be represented using array which is a linear data structure, contrast to a tree, which is a non-linear data structure. Does that mean that binary heap represented using an array is no longer a tree?

You're confusing the model--the conceptual view of the heap--with the implementation.
A binary heap is a tree that is implemented in an array. That is, we allocate a fixed block of memory and reference it as though it's a tree. We can do that because the binary heap is a very special type of tree. In concept this is not much different than how we implement a two-dimensional array.
Consider a two-dimensional array declared as a[3,4]. Most languages allocate that as a single block of memory--a linear array--of size 12. But we address it as though it's a two-dimensional structure. The compiler converts our 2D addressing to one-dimensional array indices (assuming row-major ordering), like this:
1 2 3 4 5 6 7 8 9 10 11 12
| Row 1 | Row 2 | Row 3
In our two-dimensional view it looks like this:
1 2 3 4
5 6 7 8
9 10 11 12
So a[2,3] resolves to index 7.
What does that have to to with heaps?
Because a binary heap is a complete binary tree in which all levels except possibly the last are full, and the last is left-filled (i.e. all empty space is on the right side of the last level), we can overlay a tree structure on the array in much the same way we overlay the two-dimensional array.
We know that the first element of the array is the root of the heap. We know that the next two array elements are children of the root. The next four elements are those children's children, and so on. So in a binary heap with 7 nodes we have:
Index 1 - root node
Indices 2 and 3 - Children of root node
Indices 4,5,6,7 - Children of root's children
(4 and 5 are children of the node at index 2. 6 and 7 are children of the node at index 3).
That leads to a view of the array that looks like this:
1
2 3
4 5 6 7
8 9 10 11 12 13 14 15
Or, viewed as a tree:
1
2 3
4 5 6 7
8 9 10 11 12 13 14 15
The binary heap is still a tree. We're just using our knowledge of the special nature of a binary heap to implement it more efficiently than we can implement other types of trees.
Yes, we are using a linear data structure to implement a non-linear data structure. But that's true of all the data structures we use. Early processors (think 8086 and before) viewed memory as essentially one big array. Software would essentially split that up into different areas for operating system, program code, processor stack, process heap, etc. And within the process heap (again, one big linear data structure), programs would allocate and deallocate individual blocks to build non-linear data structures. Even today's systems, with memory virtualization and address translation, things work much the same way: your program allocates large blocks of linear memory and manages them, parceling out small pieces for non-linear data structures.
And then there's the linked list: a linear data structure that's implemented in terms of a non-linear data structure. Again, the model is a list--a linear data structure. The implementation is not linear at all.
And then consider implementing a linked list in an array. Each element of the array contains the node data and an index to the next item in the list. Traversed in order, the list nodes might be at array indices 1,7,5,4,6,2,3. Whether that's a linear or non-linear data structure depends on how you're looking at the problem. Or perhaps which part of the implementation you're looking at. Again, the model of the list is linear. And the implementation is in a linear data structure (the array). But the first node in the list is at the beginning of the array, the second node is at the end, and the nodes in the middle are in essentially random order. It's not linear at all!
You must learn to separate the model from the implementation.

The answer is no, we can represent how we want, but it will be a tree. The point is here, is there no limitations for all properties of binary heap when we represent it as an array.

Related

In what order does a minheap sort?

I've been reading various definitions on minHeap and maxHeap. I stumbled upon statements which say:
minHeap is used to sort in descending order.
maxHeap is used to sort in ascending order.
Statements taken from the "Note" in https://www.geeksforgeeks.org/heap-sort-for-decreasing-order-using-min-heap/ .
But when I implement minHeap using PriorityQueue<Integer> in Java with default comparator, and poll() it, I get the minimum element. Why is that?
Thanks to anybody who's trying to help :).
The explanation in the blog is correct
While having a close look at the heapSort() function, it has smartly made use of min heap. The smallest element of the array gets replaced with the last element and size of heap is reduced by 1 to again heapify() it.
arr[0] -> represents the smallest element.
In every iteration, for i from n-1 to 0, the arr[0] is swapped with the arr[i] and heap is again heapified with size of 1 smaller than previous iteration.
min-heap and max-heap don't sort. You can use a min-heap or max-heap to sort, but in standard use, heaps aren't sorted. Instead, they arranged in what's called heap order. This arrangement makes it efficient to add items, and to remove the smallest (or largest) while keeping the data in the proper order.
For example, here's an illustration of a min-heap:
1
3 2
4 7 6 5
That follows the rule that no child is larger than its parent. The resulting array representation of that heap is [1,3,2,4,7,6,5]. Note that there are other valid heaps with those same numbers. For example, both of the below are valid, as well:
1 1
2 5 2 3
4 3 6 7 4 5 6 7
The corresponding array representations are [1,2,5,4,3,6,7] and [1,2,3,4,5,6,7].
Max-heap is similar, except the rule is that no child can be larger than its parent.
The Wikipedia article on binary heap explains this all very well.
Now, when you're talking about using heap sort, you build a heap and then repeatedly swap the root element with the last element in the array, reduce the count and then re-heapify. So you build the sorted array from back to front. If you use a min-heap, then the root (smallest value) will be at the end of the array.
So if you want to sort in descending order with heap sort, you use a min-heap.
The basic idea is to sort in place. Every time the algorithm polls from the heap, the heaps size shrinks by one. So one place at the end of the array is not part of the heap anymore. In this index the n-th smallest number is placed.
// One by one extract an element from heap
for (int i = n - 1; i >= 0; i--) {
// Move current root to end
swap(arr[0], arr[i]);
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
So the explanation why your algorithm using a PriorityQueue behaves so oddly is that you use a separate array for output. You could either switch to a max-heap and stick to your approach or fill the output-array in reverse. Both should produce the same behavior.

Suitable data structure for Java 1000*1000 matrix.

I am practising java programming. I encountered a problem which requires 1000 x 1000 matrix which stores integers value less than 1500
I would want to navigate across all the elements
I might need to fetch max element and its 4 adjacent elements.
What is the best data structure which doesn't affect performance?
1 2 3 4
5 6 7 8
9 10 11 12
12 14 15 16
for the element 11 --> 7, 10, 12, 15 are adjacent elements.
what is wrong with the 2d array data structure?
to get an adjecent of a number at i,j return [i-1][j],[i+1][j],[i][j+1],i[j-1] (you will have to deal with cases where i is zero etc)...
as performance goes, its O(1), doesn't get any better than that...
If you are talking about finding the location of the element. if the matrix is sorted you can simply do a binary search.
A 2dim Array of shorts:
-> short [][] matrix = new short[1000][1000];
| Added variable matrix of type short[][] with initial value [[S#1794d431
Generate in a second, few MB in size. What could be better than that?

Maximum size of 2D array in Java

I have to create 1000 heaps, each of which can contain 10^6 nodes. For easy access of the nodes, for deletion of nodes and for updating keys of nodes, I am planning to create a 2D array of size 10^6 * 1000 in which I'll be storing the references of nodes. But, is an array of such a big size possible to create in Java?
Is there a better way to access a particular node from the heaps without creating an array?
I could go through each node of the heap in order to search for my node, but this process will be of the order n for 1 heap, and if I have to perform a deletion of a particular node from all heaps, the process would take be of the order 1000*n.
If you need more memory than max value of int you can use sun.misc.Unsafe. See here: https://dzone.com/articles/understanding-sunmiscunsafe
Java arrays are indexed by ints, so the maximum index is 2^31 - 1, which is 2147483647 (approx. 2E9), so you should be ok with your 1E9 sized array. However, you'll need to have enough RAM, don't forget a billion longs will take 8GB of ram.
There's a much more detailed discussion in Do Java arrays have a maximum size?

Programmatically determine whether an array could be the result of a Weighted Quick Union algorithm on a set of 10 items?

I'd like to be able to programmatically examine an array and determine whether or not it could have been the result of a Weighted Quick Union algorithm. For those of us who need a refresher, a java implementation of Weighted Quick Union is here.
The basic idea of the weighted quick union algorithm is that is always connects the smaller tree to the larger one in order to minimize height, thus optimizing any traversal functions.
For example, an array that looks like 8 4 8 8 8 3 8 3 9 7 could not be the result of Weighted Quick Union because it contains a cycle, 9->7->3->8->9
An array like 8 0 9 3 6 6 0 4 8 0 cannot be a weighted quick union because the height of the trees together is 4, which is more than log(N) (where N is 10, the size of the initial array).
However, an array like 0 1 2 8 4 1 1 7 8 9 could have been the result of a weighted quick union.
I'd like to write a Java function like this:
public static boolean canBeResultOfWeightedQuickUnion(int[] id){
//returns whether or not the given array of ints could have been the result of a weighted quick union
}
How could I go about writing a method like this, ideally using the data structure available here?
"An array like *** cannot be a weighted quick union because the height of the trees together is 4, which is more than log(N) (where N is 10, the size of the initial array)."
In fact the maximum height in this case is ceil(log_2(N)), which is 4. To check this, just keep merging trees with the same height from the start
This property remains for all subtrees, and it is a very good answer for your question since you can just check this property.
The question that stills is how can you do this with most efficiency. I suppose that you just received an array and is checking it. So no other info is available. If this is the case, you can just create a auxiliary array for the height. Then you must go throught the id array, find the leafs and in a second step recursively go from the leafs to the roots updating the values of the heights and comparing to the number of elements in the subtree.

Best data structure to store and manipulate my data?

I am writing a simple Java program that will input a text file which will have some numbers representing a (n x n) matrix where numbers are separated by spaces. for ex:
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
I then want to store these numbers in a data structure that I will then use to manipulate the data (which will include, comparing adjecent numbers and also deleting certain numbers based on specific rules.
If a number is deleted, all the other numbers above it fall down the amount of spaces.
For the example above, if say i delete 8 and 9, then the result would be:
() 2 3 ()
1 6 7 4
5 1 2 3
4 5 6 7
so the numbers fall down in their columns.
And lastly, the matrix given will always be square (so always n x n, where n will be always given and will always be positive), therefore, the data structure has to be flexible to virtually accept any n-value.
I was originally implementing it in a 2-d array, but I was wandering if someone had an idea of a better data structure that I could use in order to improve efficiency (something that will allow me to more quickly access all the adjacent numbers in the matrix (rows and columns).
Ultimately, mu program will automatically check adjacent numbers against the rules, I delete numbers, re-format the matrix, and keep going, and in the end i want to be able to create an AI that will remove as many numbers from the matrix as possible in the least amount of moves as possible, for any n x n matrix.
In my opinion, you yo know the length of your array when you start, you are better off using an array. A simple dataType will be easier to navigate (direct access). Then again, using LinkedLists, you will be able to remove a middle value without having to re-arrange the data inside you matrix. This will leave you "top" value as null. in your example :
null 2 3 null
1 6 7 4
5 1 2 3
4 5 6 7
Hope this helps.
You could use one dimensional array with the size n*n.
int []myMatrix = new myMatrix[n * n];
To access element with coordinates (i,j) use myMatrix[i + j * n]. To fall elements use System.arraycopy to move lines.
Use special value (e.g. Integer.MIN_VALUE) as a mark for the () hole.
I expect it would be fastest and most memory efficient solution.
Array access is pretty fast. Accessing adjacent elements is easy, as you just increment the relevant index(s) (being cognizant of boundaries). You could write methods to encapsulate those operations that are well tested. Having elements 'fall down' though might get complicated, but shouldn't be too bad if you modularize it out by writing well tested methods.
All that said, if you don't need the absolute best speed, there are other options.
You also might want to consider a modified circularly linked list. When implementing a sudoku solver, I used the structure outlined here. Looking at the image, you will see that this will allow you to modify your 2d array as you want, since all you need to do is move pointers around.
I'll post a screen shot of relevant picture describing the datastructure here, although I would appreciate it if someone will warn me if I am violating some sort of copy right or other rights of the author, in which case I'll take it down...
Try a Array of LinkedLists.
If you want the numbers to auto-fall, I suggest you to use list for the coloumns.

Categories

Resources