Java实现堆排序算法

什么是堆?

 
堆数据结构是一个数组对象,可以很容易地将其可视化为完整的二叉树。有两种类型的堆。第一个是最大堆,第二个是最小堆。最大堆是二进制树的一种特殊类型。最大堆的根大于其子根。另一个堆是“最小堆”,这也是一种特殊类型的堆,其根值比其子项的值低。我们可以使用堆排序算法对数组值进行排序。在此算法中,将使用生成的堆来重建堆。堆排序的复杂度为O(n.log(n))。堆排序最慢,但对于大型数据集来说是更好的选择。堆的所有节点还满足以下关系:每个节点上的键值至少与其子键值一样大。
 
 Java堆排序 Java堆排序
无花果最大堆无花果堆
 

堆排序的优点

  1. 堆排序算法表现出一致的性能。与最差情况下的性能,最佳情况下的性能,平均情况下的性能复杂度相同,O(n log n)
  2. 堆排序算法非常有效。这对于排序大量元素非常有效。这意味着没有其他排序算法可以在比较中表现更好。
  3. 内存使用量最少。相反,合并排序算法需要更多的存储空间。同样,Quicksort算法由于具有递归特性,因此需要更多的堆栈空间。
  4. 堆排序算法比其他同等有效的排序算法更易于理解,因为它不使用递归。

堆排序的局限性

  1. 这不是一个稳定的排序。
  2. 它需要更多的处理时间。

堆排序算法

  1. 以二叉树形式排列节点。
  2. 节点应按照特定规则进行排列。
  3. 用户在指定的限制内输入堆的大小。该程序使用节点具有随机生成的键值的方式生成相应的二叉树。
  4. 生成堆操作:设“ n”为树中的节点数,“ i”为树的键。为此,程序使用称为“堆”的操作。调用Heapify时,“ i”的左右子树都是堆。Heapify的功能是通过与较大的子项交换自身,使“ i”安定下来。
  5. 删除最大元素:程序通过与最后一个元素交换来删除根堆中最大的元素。
  6. 该程序执行Heapify(新的根),以便生成的树满足heap属性。
  7. 重复步骤3到步骤6,直到堆为空。
示例1
 
此示例显示堆排序的工作方式。
 
考虑使用堆进行排序的数字76、21、20、95、16、19、45、45、23。
  1. 首先,我们从列表中选取第一个元素76。将其作为根节点。
  2. 接下来,从列表中选择第二个元素21。将其插入到根节点76的左侧。
  3. 然后,从列表中取出第三个元素20进行插入。将其插入到根节点的右侧。
  4. 取第四个元素95。将其插入左侧节点21。插入的元素大于父元素,因此将95与21交换。但是父节点76小于子节点95,因此交换了95和76。 。交换后95成为根节点。
  5. 考虑下一个要插入树中的元素16。将其插入左侧。存在左节点,因此将其插入到76的右侧。
  6. 元素19插入到95的右侧,因为左侧变满了。将元素19插入节点20的左侧。
  7. 现在,元素45将插入到20的右侧。但是,父元素的值小于子元素的值,因此将45换为20。
  8. 现在,右侧已完全填充,因此在左侧添加下一个元素45。元素45插入左侧的最后一个节点,即21。但是,父元素的值小于子元素的值,因此将45与21交换。
  9. 将最后一个元素23插入到左侧节点45中。45的左侧已经填充,因此将元素23插入45的右侧。
  10. 最后,我们得到了排序的堆树。
Java堆排序
 
用于堆排序的Java示例程序
 
 
public class HeapSortEx {
	public static void main(String a[]) {
		int i;
		// Numbers which are to be sorted
		int n[] = { 76, 21, 20, 95, 16, 19, 45, 45, 23 };
		// Displays the numbers before sorting
		System.out.print("Before sorting, numbers are ");
		for (i = 0; i < n.length; i++) {
			System.out.print(n[i] + " ");
		}
		System.out.println();
		// Sorting in ascending order using Heap Sort
		for (i = n.length; i > 1; i--) {
			initializeheapSort(n, i - 1);
		}
		// Displaying the numbers after sorting
		System.out.print("After sorting, numbers are ");
		for (i = 0; i < n.length; i++) {
			System.out.print(n[i] + " ");
		}
	}

	public static void initializeheapSort(int n[], int n_ubound) {
		int i, o;
		int lChild, rChild, mChild, root, temp;
		root = (n_ubound - 1) / 2;
		for (o = root; o >= 0; o--) {
			for (i = root; i >= 0; i--) {
				lChild = (2 * i) + 1;
				rChild = (2 * i) + 2;
				if ((lChild <= n_ubound) && (rChild <= n_ubound)) {
					if (n[rChild] >= n[lChild])
						mChild = rChild;
					else
						mChild = lChild;
				} else {
					if (rChild > n_ubound)
						mChild = lChild;
					else
						mChild = rChild;
				}
				if (n[i] < n[mChild]) {
					temp = n[i];
					n[i] = n[mChild];
					n[mChild] = temp;
				}
			}
		}
		temp = n[0];
		n[0] = n[n_ubound];
		n[n_ubound] = temp;
		return;
	}
}
  1.  
输出
 
Java堆排序
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值