In the Java data structure and algorithm (v)--the queue we introduced the priority queue, the priority queue is an abstract data type (ADT), which provides a way to delete the maximum (or minimum) key value of the data item, the method of inserting the data item, the priority queue can be implemented with an ordered array, This implementation, although the time complexity of deleting the maximum data item is O (1), the insertion takes a long time O (N), because the average number of data items to be moved in each insert is to ensure that the array remains orderly after insertion.
This blog we introduce another kind of data structure-heap, note here the heap and our Java language, the C + + language and other programming languages in memory of the "heap" is not the same, where the heap is a tree, the priority queue implemented by the insertion and deletion of the time complexity is O (Logn), This way, although the deletion time slows down, but the insertion time is much faster, when the speed is very important, and there are many insert operations, you can choose to use the heap to implement the priority queue.
1, the definition of the heap
①, it is a complete binary tree, in addition to the last layer of the tree node does not need to be full, the other layers from left to right are full. Note the following two cases, the second last layer from left to right in the middle of the break, then is not a complete binary tree.
②, which is usually implemented using arrays.
This is an array-implemented two-fork tree, assuming that the index value of the node is index, then:
The left child node of the node is 2*index+1,
The right child node of the node is 2*index+2,
The parent node of the node is (index-1)/2.
③, the keyword for each node in the heap is greater than (or equal to) the keyword of the node's child node.
Here to notice the difference between the heap and the previous two-fork search tree, the keyword of the left child node of all the nodes in the binary search tree is smaller than the right child node keyword, and in the binary search tree, the node can be traversed sequentially by a simple algorithm. In the heap, however, it is difficult to traverse the nodes sequentially, as shown in the fact that the heap is arranged in descending order from the root node to the leaf node, the left node of the specified node or the right node, and the upper or lower nodes because they are not on the same path, their keywords may be larger or smaller than the specified node. So the heap is weakly ordered relative to the binary search tree.
2. Traversal and Lookup
As we said earlier, the heap is weak, so it is very difficult to traverse the heap, basically, the heap does not support traversal.
For the lookup, due to the nature of the heap, there is not enough information in the lookup process to decide which of the two child nodes of the node to choose to move to the next layer, so it is difficult to find a keyword in the heap.
As a result, the heap seems to be very close to unordered, but these two operations are sufficient for fast removal of the largest (or smallest) node, the root node, and the ability to quickly insert new nodes.
3. Removal
Removal refers to the deletion of the largest node (or smallest) of the keyword, which is the root node.
The index of the root node in the array is always 0, i.e. Maxnode = heaparray[0];
After moving the root node, the tree is empty with a root node, that is, the array has an empty unit of data, which we must fill in.
The first method: it is time-consuming to move all the data items of an array forward by one cell.
The second method:
①, removing the root
②, move the last node to the root location
③, filter the node down until it is below a node greater than it, and is less than its node.
The steps are as follows:
Figure A indicates that the last node is moved to the root node, and figures B, C, d indicate that the node is filtered down to the appropriate position, its appropriate position is at the lowest level (sometimes in the middle), and figure E represents the scene of the node in the correct position.
Note: When filtering down, compare the target node to its child nodes, and who will swap the position with the big one.
4. Insert
Inserting nodes is also easy, when inserting, select up filter, the node initially inserted into the last empty cell of the array, and the size of the array is increased by one. The algorithm is then filtered up.
Note: Up and down, filtering up is only compared with a parent node and stops filtering when it is smaller than the parent node.
5. Complete Java Heap Code
First we need to know some of the main points of using arrays to represent heaps. If the index of the node in the array is x, then:
The left child node of the node is 2*index+1,
The right child node of the node is 2*index+2,
The parent node of the node is (index-1)/2.
Note: When the "/" symbol is applied to an integer, it performs the division, and the resulting value is rounded down.
Package Com.ys.tree.heap;public class Heap {private node[] heaparray;private int maxsize;private int currentsize;public H EAP (int mx) {maxSize = Mx;currentsize = 0;heaparray = new Node[maxsize];} public Boolean isEmpty () {return (CurrentSize = = 0)? True:false;} public Boolean isfull () {return (CurrentSize = = maxSize)? True:false;} public boolean insert (int key) {if (Isfull ()) {return false;} Node NewNode = new node (key); Heaparray[currentsize] = Newnode;trickleup (currentsize++); return true;} Adjust public void trickleup (int index) {int parent = (index-1)/2;//parent node index node bottom = Heaparray[index];//Add new tail node to B Ottom in while (Index > 0 && heaparray[parent].getkey () < Bottom.getkey ()) {Heaparray[index] = heaparray[ Parent];index = Parent;parent = (parent-1)/2;} Heaparray[index] = bottom;} Public Node Remove () {node root = heaparray[0];heaparray[0] = heaparray[--currentsize];trickledown (0); return root;} Adjust down public void trickledown (int index) {Node top = Heaparray[index];int largEchildindex;while (Index < CURRENTSIZE/2) {//while node have at least one childint Leftchildindex = 2 * index + 1;int RI Ghtchildindex = Leftchildindex + 1;//find larger childif (Rightchildindex < currentsize &&//rightchild exists? Heaparray[leftchildindex].getkey () < Heaparray[rightchildindex].getkey ()) {largechildindex = RightChildIndex;} else {largechildindex = Leftchildindex;} if (Top.getkey () >= Heaparray[largechildindex].getkey ()) {break;} Heaparray[index] = Heaparray[largechildindex];index = Largechildindex;} Heaparray[index] = top;} Changes a data public in the heap from the index to a boolean change (int index, int newvalue) {if (Index < 0 | | Index >= currentsize) {return false;} int oldValue = Heaparray[index].getkey (), Heaparray[index].setkey (NewValue), if (OldValue < NewValue) {Trickleup ( index);} else {trickledown (index);} return true;} public void Displayheap () {System.out.println ("Heaparray (array format):"), for (int i = 0; i < currentsize; i++) {if (heaparray[i]! = null) {System.out.print (HEaparray[i].getkey () + "");} else {System.out.print ("--");}}}} class Node {private int idata;public node (int key) {iData = key;} public int GetKey () {return iData;} public void Setkey (int key) {iData = key;}}
Java Data structures and algorithms (14)--Heap