堆排序 Java实现

    堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。

  堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值。

堆排序的基本思路:

  a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

  b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

  c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

升序排序,则构建大顶堆。

package nuc.edu.lisheng;

import java.util.Arrays;

public class HeapSort {
	public static void main(String[] args) {
		int[] a = { 58, 4, 5, 9, 36, 27, 1, 3, 58 };
		HeapSortFianl(a);
		System.out.println(Arrays.toString(a));
	}
    //是否排序完成
	public static boolean ifend(int[] a) {
		// true代表还要继续,即没有排序好
		boolean ifend = true;
		A: for (int index = a.length - 1; index > 0; index--) {
			if (a[index] < a[index - 1]) {
				ifend = false;
				break A;
			}
		}
		return ifend;
	}
    //判断a是否为奇数。(从0开始)完全二叉树中奇数索引在左,偶数索引在右。左右对应的交换操作斌不相同
	public static boolean odd(int a) {
		if (a % 2 == 0) {
			return false;
		} else {
			return true;
		}
	}
    //左右节点与父节点比较大小,交换
	public static void sortHeap(int[] a, int i, int changeIndex) {
		//如果是偶数
		if (!odd(i)) {
			int left = i - 1;
			int father = (i - 1) / 2;
			if (a[i] > a[father]) {
				int num = a[i];
				a[i] = a[father];
				a[father] = num;
			}
			if (a[left] > a[father]) {
				int num = a[left];
				a[left] = a[father];
				a[father] = num;
			}
		} else {
			//如果是奇数,且在可操作的最后一位,那么没有右节点,直接比较左节点即可
			if (i == changeIndex) {
				int father = i / 2;
				if (a[i] > a[father]) {
					int num = a[i];
					a[i] = a[father];
					a[father] = num;
				}
			} else {
				//左右都有,都比较
				int right = i + 1;
				int father = i / 2;
				if (a[i] > a[father]) {
					int num = a[i];
					a[i] = a[father];
					a[father] = num;
				}
				if (a[right] > a[father]) {

					int num = a[right];
					a[right] = a[father];
					a[father] = num;

				}
			}

		}
	}

	public static void getMaxHeap(int[] a, int changeIndex) {
		//从可操作的最后一位往后比较,直到1为止。
		for (int i = changeIndex; i > 0; i--) {
			sortHeap(a, i, changeIndex);
		}
	}
    //可操作的最后一位与守卫交换
	public static void changeFirstAndEnd(int[] a, int changeIndex) {
		int num = a[changeIndex];
		a[changeIndex] = a[0];
		a[0] = num;

	}

	public static void HeapSortFianl(int[] a) {
		int changeIndex = a.length - 1;
		A: while (true) {
			getMaxHeap(a, changeIndex);
			changeFirstAndEnd(a, changeIndex);
			changeIndex--;
			if (ifend(a)) {
				break A;
			}
		}

	}
}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值