数组排序——堆排序

数组排序——堆排序


1、数组排序之堆排序:

        堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。

(1)用大根堆排序的基本思想:

        A:先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区。

        B:再将关键字最大的记录R[1](即堆顶)和无序区的最后一个 记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n], 且满足R[1..n-1].keys≤R[n].key

        C:由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。

        D:然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。

        E:直到无序区只有一个元素为止。   

(2)大根堆排序算法的基本操作:

        A:初始化操作:将R[1..n]构造为初始堆;

        B:每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。

2、代码演示

package cn.itcast_01;

public class ArraySort_heapSort {
	public static void main(String[] args) {
		// 定义一个数组
		int[] arr = { 47, 35, 26, 26, 18, 7, 13, 19 };
		// int[] arr = { 11, 3, 454, 231, 87, 334, 0, 1, 3422, 55, 10, 4324 };
		// int[] arr = { 24 };
		// int[] arr = {};
		System.out.println("排序前:");
		printArray(arr);

		// 调用堆排序算法
		int n = arr.length;
		heapSort(arr, n - 1);

		System.out.println("排序后:");
		printArray(arr);
	}

	// 堆排序heapSort()+sift()
	// 调整算法sift()
	public static void sift(int r[], int k, int m) {
		// 你要调整的结点是k
		int i = k;
		// 堆中最后一个结点的编号是m,j是i的左孩子结点
		int j = 2 * i + 1;
		int temp = 0;
		while (j <= m) {
			if (j < m && r[j] < r[j + 1])
				j++;
			if (r[i] > r[j])
				break;
			else {
				temp = r[i];
				r[i] = r[j];
				r[j] = temp;
				i = j;
				j = 2 * i + 1;
			}
		}
	}

	// 堆排序heapSort()
	// n是数组下标的最大值:7
	public static void heapSort(int r[], int n) {
		int temp = 0;
		// 建立大顶堆
		for (int i = n / 2; i >= 0; i--) {
			sift(r, i, n);
		}

		// 逐步取出堆顶,再调整堆
		for (int i = 0; i < n; i++) {
			temp = r[0];
			r[0] = r[n - i];
			r[n - i] = temp;
			sift(r, 0, n - i - 1);
		}

	}

	// 数组遍历
	public static void printArray(int[] arr) {
		System.out.print("[");
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length - 1) {
				System.out.print(arr[i]);
			} else {
				System.out.print(arr[i] + ", ");
			}
		}
		System.out.println("]");
	}
}




  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值