Heap (create, delete, insert) and heap sort Java implementation

Heap and Heapsort

1. Heap (big root heap)

A heap can be defined as a complete binary tree with parental dominance.

Heaps also inherit some properties of full binary trees.

Parental advantage, that is, the key value of each node is always greater than its child nodes.

So we can think that on the path from any node to a leaf (of course, this leaf is the descendant of the node), the key value is always decreasing, or non-increasing (when the key value of the child node is allowed to be the same as that of the parent node) when equal).

Characteristics of the heap:

1. A complete binary tree of n nodes whose height is floor(log2(n))

2. The root of the heap is always the largest element

3. Its subtree is also a heap

4. When implementing a heap with an array, the elements of the array head can be reserved so that n nodes occupy positions 1-n respectively. In this way, the array should be initialized to a length of n+1, and the array should have the following properties:

          4.1. The parent node always occupies the first floor(n/2) position, and the leaf node will occupy the last ceil(n/2) position. Because it inherits the properties of a complete binary tree, this rule is for the right side of the last layer. A heap of dissatisfaction is also established.

          4.2. If the position of a parent node is i (1≤i≤floor(n/2)), then its child node (if it exists) position should be 2i and 2i+1; correspondingly, the child node's position is 2i and 2i+1. When the position is i, the position of its parent node should be floor(i/2)

An array is adjusted to a heap, and the two rules 4.1 and 4.2 play an important role in the algorithm for adjusting the heap.

The Java implementation of the heap, including the creation of the heap, the deletion of any index position of the heap, and the insertion of the heap:

package com.ryo.algorithm.heap;

import com.ryo.algorithm.util.Util;

/**
 * Adjust the heap using the idea of ​​insertion sort
 * @author shiin
 */
public class InsertHeap implements Heap{
	
	private int[] heap;
	private int size;
	
	public InsertHeap(int[] arr) {
		if(arr != null) {
			heap = new int[arr.length+1];
			size = arr.length;
			if(size > 1) {
				for(int i=0 ;i<size ;i++) {
					heap[i+1] = arr[i];
				}
				buildHeap();
			}
		}
	}
	
	@Override
	public void buildHeap() {
		int floor = (heap.length-1)/2;//The index of the last parent node of the lower bound
		int i = floor;
		int j ,temp ,nextindex;
		while(i > 0) {
			temp = heap[i];
			j = i;
			while(j <= floor) {
				nextindex = getBigerIndex(j);
				if(temp < heap[nextindex]) {
					heap[j] = heap[nextindex];
				}
				else
					break;
				j = nextindex;
			}
			heap[j] = temp;
			i--;
		}
	}
	
	/**
	 * Insert an int and put it in the appropriate position
	 * @param newint new element
	 */
	@Override
	public void insert(int newint) {
		int[] temp = new int[heap.length+1];
		for(int i=0 ;i<temp.length-1 ;i++) {
			temp[i] = heap[i];
		}
		int index = heap.length;
		while(index > 1) {
			if(newint > temp[index/2]) {
				temp[index] = temp[index/2];
				index = index/2;
			}
			else
				break;
		}
		temp[index] = newint;
		heap = temp;
	}

	/**
	 * delete the element at the specified index
	 * The basic idea is to use the element at the end to replace the element at the deleted position and then adjust the heap
	 * @param index target index, starting from 1 as root
	 */
	@Override
	public void delete(int index) {
		heap[index] = heap[heap.length-1];
		int[] temp = new int[heap.length-1];
		for(int i=0 ;i<temp.length ;i++) {
			temp[i] = heap[i];
		}
		heap = temp;
		buildHeap();
	}
	
	/**
	 * Compare the size of two child nodes and return the index of the larger node
	 * @param root root node location
	 * @return the index of the larger child node
	 */
	private int getBigerIndex(int root) {
		if(2*root + 1 > size) {
			return 2*root;
		}
		else {
			if(heap[2*root] > heap[2*root+1])
				return 2*root;
			else
				return 2*root+1;
		}	
	}
	

	@Override
	public int[] getHeap() {
		return this.heap;
	}

	@Override
	public int size() {
		return this.size;
	}

}

Heap sort Java implementation:

package com.ryo.algorithm.sort;

import com.ryo.alogorithm.heap.InsertHeap;

public class HeapSort implements Sort{

	@Override
	public int[] sort(int[] arr) {
		int[] heap = new InsertHeap(arr).getHeap();
		return heapSort(heap);
	}
	
	private int[] heapSort(int[] heap) {
		int cursor = heap.length-1;
		int[] result = new int[heap.length-1];
		int i = result.length-1;
		int nextindex,temp,j;
		while(cursor > 0) {
			result[i] = heap[1];
			j = 1;
			temp = heap[cursor];
			while(j*2 < cursor) {
				nextindex = getBigerChildIndex(heap ,j);	
				if(!compareAndSet(heap ,temp ,nextindex))
					break;		
				j = nextindex;
			}
			heap[j] = temp;
			i--;
			cursor--;
		}
		return result;	
	}
	
	/**
	 * Return the larger child node index
	 * @param heap target array
	 * @param index parent node index
	 * @return larger child node index
	 */
	public int getBigerChildIndex(int[] heap ,int index) {
		if(heap[2*index] > heap[2*index+1]) {
			return 2*index;
		}
		else
			return 2*index+1;
	}
	
	/**
	 * Based on an idea of ​​insertion sort
	 * If the child is greater than the value, only the value of the parent node of the child is set to the value of the child, and the child is not changed
	 * @param heap target array
	 * @param value the value to compare
	 * @param child The index of the larger child node, which should be passed in by the getBigerChildIndex method
	 * @return whether it needs to continue to compare downwards
	 */
	public boolean compareAndSet(int[] heap ,int value ,int child) {
		if(value < heap[child]) {
			heap[child/2] = heap[child];
			return true;
		}
		else
			return false;
	}
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325658884&siteId=291194637