主页 > 软件开发  > 

数据结构与算法之排序算法-选择排序

数据结构与算法之排序算法-选择排序

排序算法是数据结构与算法中最基本的算法之一,其作用就是将一些可以比较大小的数据进行有规律的排序,而想要实现这种排序就拥有很多种方法~

那么我将通过几篇文章,将排序算法中各种算法细化的,详尽的为大家呈现出来:

📚 非线性时间比较类:

📕 插入类排序:数据结构与算法之排序算法-插入排序-CSDN博客

📖 直接插入排序

📖 希尔排序

📕 交换类排序:数据结构与算法之排序算法-快速排序(分治)-CSDN博客

📖 冒泡排序

📖 冒泡排序-优化

📖 快速排序(Hoare,挖坑法,前后指针法)

📖 快速排序-优化

📕 选择类排序:[本篇]

📖 简单选择排序

📖 堆排序

📕 归并类排序:数据结构与算法之排序算法-归并排序-CSDN博客

📖 归并排序

📚 线性时间非比较类:

📕 非比较类排序:数据结构与算法之排序算法-(计数,桶,基数排序)-CSDN博客

📖 计数排序

📖 桶排序

📖 基数排序

一、选择排序

稳定性:不稳定

时间复杂度:O(n^2)

额外空间复杂度:O(1)

选择排序是排序算法中最简单直观的排序算法之一,还记得冒泡排序吗?在冒泡排序中,我们是通过多次遍历数组,然后将此次遍历中最大的元素放到遍历范围的最后,选择排序和冒泡排序有一些相似之处:

冒泡排序的核心思想:不断寻找最大的元素并放到最后。 选择排序的核心思想:不断寻找最小的元素并放到最前。

① 选择排序(循环嵌套)

📚 算法思想:

选择排序:通过两层循环,外层循环(int i = 0;i < len - 1;i++)代表从 i 开始,进行内层循环(int j = i + 1;j < len;j++)来寻找此次循环中的最小值,并将最小值放在 i 的位置~

⭐ 图示:

📖 代码示例:

public static void selectionSort(int[] arr){ int len = arr.length; for(int i = 0;i < len - 1;i++){ int minIndex = i; for(int j = i + 1;j < len;j++){ if(arr[j] < arr[minIndex]){ minIndex = j; } } swap(arr,i,minIndex); } } ② 选择排序(双指针)

📚 算法思想:

通过每次迭代同时找到当前范围内的最大值和最小值,并且将它们分别放到数组的两端,这样可以减少直接插入排序算法的迭代次数,做到提高效率(但其实没卵用...)

使用两个指针left和right,分别指向数组的起始位置和结束位置 每次迭代中,找到当前范围内[left,right]的最小值和最大值 将最小值放到left位置,将最大值放到right位置 然后缩小范围,left++,right--,直到left和right相遇。

📖 代码示例:

public static void selectSort2(int[] array){ int left = 0; int right = array.length - 1; while(left < right){ int minIndex = left; int maxIndex = left; System.out.println(Arrays.toString(array)); for(int i = left + 1;i <= right;i++){ if(array[minIndex] > array[i]){ minIndex = i; } if(array[maxIndex] < array[i]){ maxIndex = i; } } swap(array, left, minIndex); if(left == maxIndex){ maxIndex = minIndex; } swap(array, right, maxIndex); left++; right--; } }

(可以实现一下用来练习自己的代码能力,实际应用的话还是算了,时间复杂度为O(n^2)不说,还不具有稳定性,代码长度甚至可以和优化过的快速排序一拼了也是难绷...连冒泡排序都不如...)

二、堆排序

稳定性:不稳定

时间复杂度:O(n logn)

额外空间复杂度:O(1)

堆排序的时间复杂度和快速排序一样,也是O(n logn),这是一种非常快速的排序了,并且它的额外空间复杂度为O(1),这也使得它在实际应用中也比较广泛。

📚 算法思想:

堆排序的思想也是很简单的,在之前我们学习过"优先级队列",也可以分为"大根堆","小根堆"。

不清楚什么是"优先级队列",不认识"大根堆","小根堆"的可以去我之前的文章中进行学习: Java-数据结构-优先级队列(堆)_java优先级队列获取大根堆-CSDN博客 Java-数据结构-优先级队列(堆的使用)-CSDN博客 而堆排序的实现,就是以堆中的各种方法组合起来实现的:

首先,我们需要先将数组创建成一个"大根堆",这样我们就能够做到轻易地获取数组中的最大元素。

然后对这个"大根堆"的堆顶元素(最大元素)不断的放到最后,并进行删除操作(假意的删除,其实只是在后续操作中不再访问该元素),这样直到最后,我们就能得到一个升序数组。

在这个过程中,我们需要实现"创建大根堆","向下调整"的方法,而这些方法在上面两篇博客链接中也有详细的讲解,可以移步到上述两篇博客中进行学习~

⭐ 图示:

📖 代码示例:

public void heapSort(int[] array){ //构造一个大根堆 createHeap(array); int len = array.length; for(int i = len - 1;i > 0;i--){ //将array[0]放到最后(最大的数放到最后) swap(array,0,i); //向下调整,再次变成大根堆(堆到后面的大数不再调整) siftDown(array,0,i); } } public void createHeap(int[] array){ int index = array.length; //从最后一个父结点开始,依次将父结点向前进行向下调整 for(int parent = (index - 1 - 1) / 2;parent >= 0;parent--){ siftDown(array,parent,index); } } public void siftDown(int[] array,int parent,int len){ int child = 2 * parent + 1; while(child < len){ if(child + 1 < len && array[child + 1] > array[child]){ child = child + 1; } if(array[child] > array[parent]){ swap(array,child,parent); parent = child; child = parent * 2 + 1; }else { break; } } }

那么这篇关于选择排序的文章到这里就结束啦,作者能力有限,如果有哪里说的不够清楚或者不够准确,还请各位在评论区多多指出,我也会虚心学习的,我们下次再见啦

标签:

数据结构与算法之排序算法-选择排序由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“数据结构与算法之排序算法-选择排序