七大排序算法之堆排、选择

选择排序

思想:循环一次找到一个最小值(最大值),缩小排序一个长度

时间复杂度:

平均:O(N^2)

最好:O(N^2)

最坏:O(N^2)

空间复杂度:O(1)

稳定性:不稳定排序

实现代码:

public static void selectSort(int[] arr) {
	// 每次找出一个最小值
	for (int i = 0; i < arr.length; ++i) {
		// [0, i)是有序的
		// 每循环一次,在[i, length)找出一个最小的置于i位置上
		for (int j = i; j < arr.length; ++j) {
			if (arr[j] < arr[i]) {
				swap(arr, i, j);
			}
		}
	}
}

// 优化版:每循环一次找到最大值和最小值
public static void selectSortPerfect(int[] arr) {
	int n = arr.length;
	int max, min = 0;
	for (int i = 0; i < n / 2; ++i) {
		max = i;
		min = i;
		for (int j = i + 1; j < n - i; ++j) {
			if (arr[j] < arr[min]) {
				min = j;
			}
			if (arr[j] > arr[max]) {
				max = j;
			}
			// 在[0, i)是有序的
			swap(arr, i, min);

			// 在(n-i-1, n)是有序的
			swap(arr, max, n - i - 1);
		}
	}
}

private static void swap(int[] array, int num1, int num2) {
	int tmp = array[num1];
	array[num1] = array[num2];
	array[num2] = tmp;
}

堆排序

思路:

1、建堆(在原有数组上建堆),从小到大排序建大堆

2、每次选择堆顶元素方法数组最后,堆数量-1,调整堆(向下调整)

时间复杂度:

平均:O(NlgN)

最好:O(NlgN)

最坏:O(NlgN)

空间复杂度:O(1)

稳定性:不稳定排序

代码实现:

public static void heapSort(int[] array) {
	int size = array.length;
	if (size <= 1) {
		return;
	}

	// 1、建堆(大堆)
	createHeap(array, size);
	// 2、删除堆顶元素,放置数组最后一个
	for (int i = 0; i < size; ++i) {
		heapPop(array, size - i);
	}

}

private static void createHeap(int[] array, int size) {
	// 下沉式调整, 需要从后往前遍历,
	// 从最后一个非叶子节点开始遍历
	// size - 1表示最后一个元素的下标
	// 拿着这个下标 - 1 / 2 就得到了当前元素的父节点
	for (int i = (size - 2) / 2; i >= 0; --i) {
		adjustDown(array, size, i);
	}
}

// 向下调整
private static void adjustDown(int[] array, int size, int parent) {
	int leftChild = 2 * parent + 1;// 左子树
	int rightChild = 2 * parent + 2;
	int maxChild;

	if (leftChild >= size) {
		return;
	}

	maxChild = leftChild;
	if (rightChild < size && array[rightChild] > array[leftChild]) {
		maxChild = rightChild;// 找出左右孩子的最大值
	}

	if (array[parent] > array[maxChild]) {// 满足堆条件
		return;
	}

	swap(array, parent, maxChild);
	adjustDown(array, size, maxChild);
}

private static void heapPop(int[] array, int size) {
	swap(array, 0, size - 1);
	adjustDown(array, size - 1, 0);
}

private static void swap(int[] array, int num1, int num2) {
	int tmp = array[num1];
	array[num1] = array[num2];
	array[num2] = tmp;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值