【排序3】选择排序:高效的排序算法之美

👻选择排序

选择排序的基本思想
每一趟(第i趟)在后面n-i+1(i=1,2,···,n-1)个待排序元素中 选取关键字最小的元素,作为有序子序列的第i个元素,直到n---1趟做完,待排序元素只剩下一个,就不用再选了。

🎡1、直接选择排序

直接选择排序 是一种简单直观的排序算法。它的基本思想是每次从未排序的部分中找到最小(或最大)的元素,将其与未排序部分的第一个元素交换位置,然后缩小未排序部分的范围,继续进行选择和交换,直到整个序列有序。

😊【具体步骤】:

1、在元素集合arrayi--arrayn-1中选择关键码最大(小)的数据元素

2、若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换

3、在剩余的arrayi--arrayn-2(arrayi+1--arrayn-1)集合中,重复上述步骤,直到集合剩余1个元素

如图

🪄代码示例

bash 复制代码
public static void selectSort(int[] array) {
	for (int i = 0; i < array.length; i++) {
    	int minIndex = i;
    	int j = i+1;
    	for (; j < array.length; j++) {
    		if(array[j] < array[minIndex]) {
    			minIndex = j;
        	}
        }
    	swap(array,i,minIndex);
    }
}
private static void swap(int[] array,int i,int j) {
	int tmp = array[j];
    array[j] = array[i];
    array[i] = tmp;
}

🎉【直接选择排序的特性总结】

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

🎡2、堆排序

堆排序 (Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

堆排序的关键是构造初始堆。n个结点的完全二叉树最后一个结点是第n/2个结点的孩子 。对第n/2个结点为根的子树进行筛选,使该子树成为堆。之后向前依次对各结点为根的子树进行筛选,看该结点值是否大于其左右子结点的值,若不大于,则将左右子结点中的较大值与之交换,交换后可能破坏下一级的堆,于是继续采用上述方法构造下一级的堆,直到以该结点为根的子树构成堆为止。反复利用上述调整堆的方法建堆,直到根结点。

如图

输出栈顶元素后 ,将堆的最后一个元素与栈顶元素交换,此时堆的性质被破坏。

同时,堆也支持插入操作。对堆进行插入操作时,先将新结点放在堆的末端,再对这个新结点向上执行调整操作。

🪄代码示例:

bash 复制代码
 public static void heapSort(int[] array){
	//创建大根堆
    createHeap(array);
    int end = array.length-1;
    while (end > 0) {
    	swap(array,0,end);
        siftDown(array,0,end);
        end--;
    }
}

private static void createHeap(int[] array) {
	for (int parent = (array.length-1-1)/2; parent >= 0 ; parent--) {
		siftDown(array,parent,array.length);
	}
}

private static void siftDown(int[] array,int parent,int len) {
	int child = (2*parent)+1;
    while (child < len) {
    	if(child + 1 < len && array[child] < array[child+1]) {
        	child = child+1;
        }
        if(array[child] > array[parent]) {
            swap(array,child,parent);
            parent = child;
            child = 2*parent+1;
        }else {
            break;
        }
	}
}

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

🎉【堆排序的特性总结】

  1. 堆排序使用堆来选数,效率就高了很多。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

🎉OK!今天的分享就到这里了,后面还会分享更多排序算法,敬请关注喔!!!✌️

相关推荐
唐青枫10 分钟前
Java Spring WebFlux 实战指南:用 Mono、Flux 和 WebClient 写响应式接口
java·spring
To_OC10 小时前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
小bo波13 小时前
使用Thread子类创建线程 VS 使用Runnable接口创建线程的区别
java·多线程·thread·并发编程·runnable
SamDeepThinking14 小时前
高并发场景下,CompletableFuture与ForkJoinPool该如何取舍?
java·后端·面试
用户9385156350715 小时前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法
To_OC16 小时前
手写快排次次翻车?别死背快排模板了,这才是面试官想听的底层逻辑
javascript·算法·排序算法
饼干哥哥17 小时前
Reddit VOC调研太慢?搭一个AI专家团队半小时洞察任何品类|以猫用饮水机为例
人工智能·算法·ai编程
张不才17 小时前
CPU 100% 了怎么办?Java 性能排障的标准化操作
java·后端
地平线开发者18 小时前
Transformer模型部署之性能优化指南
算法
地平线开发者18 小时前
人在途中:从“编译失败”到“模型可落地”——CUDA 自定义算子
算法·自动驾驶