选择排序

1、选择排序(Selection Sort)

1.1 算法描述

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

1.2 动画演示

选择排序动画演示

1.3 代码实现

package sort;

//平均时间复杂度:O(n²) 最好:O(n²) 最坏:O(n²)  空间复杂度:O(1)  不稳定
public class SelectSort {
	public static void main(String[] args) {
		int[] arr = { 4, 2, 0, 8, 5, 1, 3, 9, 6, 7 };
		selectSort(arr);
		print(arr);
	}

	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			int minPos = i; // 每次都要找到未排序最小元素的下标
			for (int j = i + 1; j < arr.length; j++) {
//				minPos = arr[minPos] > arr[j] ? j : minPos;
				if(arr[minPos] > arr[j])
					minPos = j;
			}
			swap(arr, i, minPos);
		}
	}

	static void swap(int[] arr, int i, int minPos) {
		int temp = arr[i];
		arr[i] = arr[minPos];
		arr[minPos] = temp;
	}

	static void print(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
	}
}

2、堆排序(Heap Sort)

2.1 算法描述

堆积是一个近似完全二叉树,满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

  • 将初始待排序关键字序列构建成大顶堆,此堆为初始的无序区;
  • 将堆顶元素与最后一个元素交换,此时得到新的无序区和新的有序区;
  • 由于交换后新的堆顶可能违反堆的性质,因此需要对当前无序区调整为新堆,然后再次将堆顶与无序区最后一个元素交换,得到新的无序区和新的有序区。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

2.2 动画演示

堆排序动画演示

2.3 代码实现

package sort;

//结点的左子结点对应的数组2*n+1,右子结点2*n+2
//平均时间复杂度:O(nlogn) 最好:O(nlogn) 最坏:O(nlogn)  空间复杂度:O(1)  不稳定
public class HeapSort {
	public static void main(String[] args) {
		int[] arr = { 2, 4, 3, 5, 6, 7, 9, 1, 8 };
		sort(arr);
		System.out.println(Arrays.toString(arr));
	}

	/**
	 * 堆排序:
	 * 1、构建大顶堆
	 * 2、交换堆顶和末尾元素
	 * 3、继续构建大顶堆
	 */
	public static void sort(int[] arr) {
		for (int i = arr.length / 2; i >= 0; i--) {
			adjustHeap(arr, i, arr.length - 1);
		}

		for (int t = arr.length - 1; t > 0; t--) {
			int temp = arr[t];
			arr[t] = arr[0];
			arr[0] = temp;
			adjustHeap(arr, 0, t - 1);
		}
	}

	// 将一个二叉树,调整成一个大顶堆
	public static void adjustHeap(int[] arr, int s, int length) {
		int temp = arr[s];
		for (int j = s * 2 + 1; j < length; j = j * 2 + 1) {
			if (j + 1 < length && arr[j] < arr[j + 1])
				j++;
			if (arr[j] <= temp)
				break;
			
			arr[s] = arr[j];
			s = j;
		}
		arr[s] = temp;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值