在java中排序堆
时间:2020-02-23 14:34:49 来源:igfitidea点击:
在本教程中,我们将看到如何在Java中实现堆。
我将划分堆中的多个部分,使其更加理解。
什么是堆?
一个 heap
是一个具有一些特殊属性的树,所以节点的值应大于或者等于(小于或者等于MIN堆的情况下)节点和树的子项应该是完整的二叉树。
二元堆
Binary heaps
是那些最多可容纳2个孩子的堆。
我们将在接下来的几个部分中使用二进制堆。
了解完整的二叉树
完整的二叉树是一个二进制树,其叶子在h或者h-1级,其中h是树的高度。
左子索引= 2 *(其父索引的索引)+1右侧索引= 2 *(其父级的索引)+2
堆的类型
有两种类型的堆。
- 最大堆
- 闵堆
max heap:它是 binary heap
其中节点的值大于节点的左左和右子。
闵堆:它是 binary heap
其中节点的值小于节点的左左和右子。
heapizing一个元素:
创建堆后,它可能无法满足堆属性。
为了再次使其堆,我们需要调整堆的位置,并且此过程称为 heapifying
要素。
为了创建一个最大堆,我们会将当前元素与其子组进行比较并找到最大值,如果当前元素不是最大值,则将其更高的左或者右侧的子元素交换。
Leapizing Element的Java代码I:
public static void heapify(int[] arr, int i, int size) { int left = 2 * i + 1; int right = 2 * i + 2; int max; if (left <= size && arr[left] > arr[i]) { max = left; } else { max = i; } if (right <= size && arr[right] > arr[max]) { max = right; } //If max is not current node, exchange it with max of left and right child if (max != i) { exchange(arr, i, max); heapify(arr, max, size); } }
堆排序的步骤
- 将数组表示为完整的二叉树。
- 左孩子将在
2*i+1
地点 - 合适的孩子将在
2*i+2
位置。 - 建立一堆。
- 所有叶节点都已满足堆属性,因此我们不需要加热它们。
- 最后的叶节点将出现在
(n-1)th
位置,所以它的父母将在(n-1)/2
位置,因此(n-1)/2
将是最后一个非叶节点的位置。 - 迭代非叶节点和
heapify
要素。 - 建立堆后,
max element
将是堆的根源。我们会与之交换(n-1)th
位置,使得最大的元素将在适当的位置,并通过减少n的大小从堆中取出。 - 交换最大元素时,它可能会干扰最大堆属性,所以我们需要再次
heapify
它。 - 完成上述步骤后,直到没有堆中的元素,我们将在最后进行排序阵列。
堆的Java代码排序
package org.igi.theitroad; import java.util.*; public class HeapSortMain { public static void buildheap(int []arr) { /* * As last non leaf node will be at (arr.length-1)/2 * so we will start from this location for heapifying the elements * */ for(int i=(arr.length-1)/2; i>=0; i--){ heapify(arr,i,arr.length-1); } } public static void heapify(int[] arr, int i,int size) { int left = 2*i+1; int right = 2*i+2; int max; if(left <= size && arr[left] > arr[i]){ max=left; } else { max=i; } if(right <= size && arr[right] > arr[max]) { max=right; } //If max is not current node, exchange it with max of left and right child if(max!=i) { exchange(arr,i, max); heapify(arr, max,size); } } public static void exchange(int[] arr,int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } public static int[] heapSort(int[] arr) { buildheap(arr); int sizeOfHeap=arr.length-1; for(int i=sizeOfHeap; i>0; i--) { exchange(arr,0, i); sizeOfHeap=sizeOfHeap-1; heapify(arr, 0,sizeOfHeap); } return arr; } public static void main(String[] args) { int[] arr={1,10,16,19,3,5}; System.out.println("Before Heap Sort : "); System.out.println(Arrays.toString(arr)); arr=heapSort(arr); System.out.println("====================="); System.out.println("After Heap Sort : "); System.out.println(Arrays.toString(arr)); } }
时间和空间复杂性
时间复杂性:最佳案例:
O(nlogn)
平均案例: O(nlogn)
最坏的情况下 : O(nlogn)
空间复杂性:由于堆排序是归档排序算法,空间复杂性是 o(1)
。
除了在堆中交换变量之外,我们不需要任何另外的空间。