更新时间:2023-01-24 14:31:45 来源:精美文章网 点击:次
丙.
堆排序不需要大量的递归或多维临时数组。这适用于数据量非常大的序列。例如,有超过百万条记录。因为快速排序和归并排序都是用递归来设计算法,所以在数据量非常大的情况下可能会出现堆栈溢出错误。
例如:
排序,按最大(最小)交换法排序,只排序10个数,这样就可以算出100000 * 10个循环:
int a[1000000];
int i,j,max,t;
for(I=0;i10我)
{
max=I;
for(j=I;j1000000j)
if(a[max]a[j])
max=j;
t=a[I];
a[I]=a[max];
a[max]=t;
}
这样来看,前10名是最大的。
扩展信息:
在堆的数据结构中,堆中的最大值总是在根节点(如果堆用在优先级队列中,堆中的最小值在根节点)。堆中定义了以下操作:
Max Heapify:调整堆末尾的子节点,使子节点始终小于父节点。
构建最大堆:对堆中的所有数据重新排序。
HeapSort:去掉第一个数据的根节点,做最大堆调整的递归运算。
来源:百度百科-堆排序
堆排序不需要大量的递归或多维临时数组。
这适用于数据量非常大的序列。
例如,有超过百万条记录。因为快速排序和归并排序都是用递归来设计算法,所以在数据量非常大的情况下可能会出现堆栈溢出错误。
例如:
排序,按最大(最小)交换法排序,只排序10个数,这样就可以算出100000 * 10个循环:
int a[1000000];
int i,j,max,t;
for(I=0;i10我)
{
max=I;
for(j=I;j1000000j)
if(a[max]a[j])
max=j;
t=a[I];
a[I]=a[max];
a[max]=t;
}
这样来看,前10名是最大的。
扩展信息:
在堆的数据结构中,堆中的最大值总是在根节点(如果堆用在优先级队列中,堆中的最小值在根节点)。堆中定义了以下操作:
Max Heapify:调整堆末尾的子节点,使子节点始终小于父节点。
构建最大堆:对堆中的所有数据重新排序。
HeapSort:去掉第一个数据的根节点,做最大堆调整的递归运算。
1.实用排序算法:选择性排序(1)选择性排序的基本思想是:每次行程(例如第I次行程,i=0,1,2,3,… n-2)从下n-i个要排序的元素中选择排序码最小的元素作为有序元素序列的第I个元素。当第n-2次旅行结束时,只有一个元素需要排序,因此不需要再次选择它。
(2)三种常用的排序方法:1直接排序,2锦标赛排序,3堆排序。其中,直接排序的思想和实现都比较简单,而且与其他排序算法相比,直接排序有一个突出的优势:3354数据移动较少。
(3)直接选择排序介绍1直接选择排序是一种简单的排序方法。其基本步骤是:1)从一组元素V[i]~V[n-1]中选择排序码最小的元素;2)如果不是这个组的第一个元素,用这个组的第一个元素来切换;3)从这组元素中剔除排序代码最小的元素,在剩余的元素V[i 1]~V[n-1]中重复步骤1和2,直到只剩下一个元素。2.直接选择排序的使用。注意,对于一类重要的元素序列,即元素规模较大但排序码相对较小的序列,它有很好的效率。因为对这种序列排序,移动操作比比较操作耗时长得多,而其他算法移动的次数比直接选择排序多,这是一种不稳定的排序方法。3.直接选择排序C功能码//function函数,直接选择排序算法排序。//函数参数,序列起点,序列终点void DSelect _ sort (const int start,const int end){ for(int I=start;我结束;I){ int min _ position=I;for(int j=I 1;j=结束;J) {//此循环用于查找最小键if(numbers[j]numbers[min _ position]){ min _ position=j;} } if (min_position!=i) {//避免与自己交换swap(numbers[min _ position],numbers[I]);(4)关于锦标赛排名的直接选择,当n比较大的时候,排名代码的比较次数是相当多的,因为在后面的比较选择中,往往会再次重复前面的比较,没有
把前一趟的比较结果保留下来。
锦标赛排序(tournament sort)克服了这一缺点。它的思想与**比赛类似,就是把待排序元素两两进行竞赛,选出其中的胜利者,之后胜利者之间继续竞赛,再选出其中的胜利者,然后重复这一过程,最终构造出胜者树,从而实现排序的目的。2,堆排序的排序过程(1)个人理解:堆排序是选择排序的一种,所以它也符合选择排序的整体思想。
直接选择排序是在还未成序的元素中逐个比较选择,而堆排序是首先建立一个堆(最大堆或最小堆),这使得数列已经“大致”成序,之后只需要局部调整来重建堆即可。建立堆及重建堆这一过程映射到数组中,其实就是一个选择的过程,只不过不是逐个比较选择,而是借助完全二叉树来做到有目的的比较选择。这也是堆排序性能优于直接选择排序的一个体现。
(2)堆排序分为两个步骤:1gt;根据初始输入数据,利用堆的调整算法形成初始堆;2gt;通过一系列的元素交换和重新调整堆进行排序。(3)堆排序的排序思路1gt;前提,我们是要对n个数据进行递增排序,也就是说拥有最大排序码的元素应该在数组的末端。2gt;首先建立一个最大堆,则堆的第一个元素heap[0]具有最大的排序码,将heap[0]与heap[n-1]对调,把具有最大排序码的元素交换到最后,再对前面n-1个元素,使用堆的调整算法siftDown(0,n-2),重新建立最大堆。
结果具有次最大排序码的元素又浮到堆顶,即heap[0]的位置,再对调heap[0]与heap[n-2],并调用siftDown(0,n-3),对前n-2个元素重新调整,……如此反复,最后得到一个数列的排序码递增序列。(4)堆排序的排序过程:下面给出局部调整成最大堆的函数实现siftDown(),这个函数在前面最小堆实现博文中的实现思路已经给出,只需做微小的调整即可用在这里建立最大堆。
选择排序的基本思想是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最大的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。
java选择排序法代码
import java.util.Random;
public class ArrayDemo {
public static void main(String[] args) {
Random random=new Random();
int[] pData=new int[10];
for(int i=0;ilt;pData.length;i++){ //随机生成10个排序数
Integer a =random.nextInt(100);
pData[i]= a;
System.out.print(pData[i]+” “);
}
System.out.println();
pData=Choose(pData);
for(int i=0;ilt;pData.length;i++){
System.out.print(pData[i]+” “);
}
System.out.println();
}
public static int[] Choose(int[] pData){
System.out.println();
int k;
for (int i = 0; i lt; pData.length; i++) {
k = i;
for (int j = i; j lt; pData.length; j++) {
if(pData[j]lt;pData[k]){k = j;}
}
int a=pData[i];
pData[i]=pData[k];
pData[k]=a;
}
return pData;
}
}
扩展资料:
其他排序方法:
简单选择排序的基本思想:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;
以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。
想在含有n个元素的序列中得到最小的前k个元素,最好采用什么排序算法是堆排序。
堆排序利用堆数据结构而设计的一种排序算法,堆排序是一种选择排序,平均时间复杂度均为O(nlogn),堆排序具有不稳定性。
堆排序作为具有以下性质的完全二叉树:大顶堆每个结点的值都大于或等于其左右孩子结点的值,或者小顶堆每个结点的值都小于或等于其左右孩子结点的值。
扩展资料:
堆排序的基本思想:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。
然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
咳咳:俗话说: 脱离业务的技术,就是耍流氓 。那么我就要提出这篇文章的灵魂一问了,请听题: 这个时候,感觉就是M个数中选择N个数 ,就是TOP N问题呀,是不是脑海中不由自主的蹦出了排序算法啦~ 哈哈,咱就按照这个思路走。
然后, 表面不慌,假装思索中ing,其实内心再想:排序算法是啥呀? 冒泡排序 ,核心思想: 相邻比较。
每次将最大的浮出水面。 快速排序 ,核心思想: 分治法+挖坑填数。 每次选择一基数,排序完成左边比基数小,右边比基数大。一直切分( 分治 ),直至选出 无序 的最大的N个整数。
堆排序(出场自带猪脚光环~) ,可以创建一个N大小的 最小堆 。然后balabala。 我就拿(内心PS:读书人的事情,怎么能说偷呢?)一下图吧,放在这里这里让大家容易理解~~ 给定一个列表array=[16,7,3,20,17,8],对其进行堆排序。
首先根据该数组元素构建一个完全二叉树,得到 然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下: 第一步:找到最后一个组(非叶节点), 左节点8 pk 擂主3 ,左孩子8胜利!然后3和8互相调换位置。 败者3 没有子节点,结束比赛。 从右到左。
组内pk, 左子树20 pk 右子树17 左子树20胜利,获得挑战擂主7的机会。 左子树20 pk 擂主7 左子树20胜利,20和7交换位置。 败者7 没有子节点,结束比赛。
从下到上, 左子树20 PK 右子树8 ,左子树20胜利。获得挑战擂主16的机会。 左子树20 pk 擂主16 左子树胜利,交换位置。 此时 败者16 含有孩子节点,将被挑战。
组内挑战开始: 左子树7 和 右子树17 组内pk,右子树17胜利。获取挑战擂主16的机会。 右子树17 和 擂主16 pk,右子树17胜利,交换位置。 败者16 无孩子节点,结束比赛。
这样就得到了 初始堆 。 哈哈,相信到这里,基本懂得同学还是懂,不懂得还是一脸XX。这是哪?我在干什么?你是谁? 1. 找到最后一个非叶节点,从右到左,从下到上 ,遍历所有 非叶节点 ; 2.若是父节点 小于 最大的子节点 ,那么交换父子节点的位置,但是要注意,交换之后 对其他节点的影响。 我们的目标是: ( 没有蛀牙…. ) 根节点一定是树中最大的值。
同时,父节点大于子节点 。 切回到我们的问题。此时,你应该基本知道了堆的概念,为什么不选最大堆呢?因为咱们选最小堆就是采用 末位淘汰制 。
将堆中最小元素剔除。 每次最小堆调整后,总会将整个堆中 最小的元素放在根节点上 ,然后我们分别取出 [N-1,M] 中的元素,若大于堆顶,则替换。然后( 随着堆的蠕动,你可以动态想想这个画面~~ ) 再次 将最小元素选出放于堆顶。
直至堆里保存的都是最大的元素。 还是上面的数组,证据在上面,咱们就开始分析啦: 咱们从i=5,最后一个元素array[5]开始说起: 父节点 :(i-1)/2=2, 他的父节点就是i=2 ,array[2]也就是3。 子节点 : 2i+1=11,等等兄得,你越界了…你根本没有孩子节点…(名侦探小胖) 于是我就大胆推测一下, 最后一个非子节点就是array[2]。 反向推理一下 :i=2时,左孩子:2i+1=5,右孩子:2i+2=6,但是最大下标是5,那么 只有一个孩子节点array[5] 也就是8。
那倒数第二个下标非叶节点的下标是啥? 博主内心独白:emmm我也不知道….继续套公式,看看有啥规律不。 数组倒数第二个下标数是i=4,(i-1)/2=1,那么 下标array[1]就是第2个父节点。 数组倒数第三个下标数是i=3,(i-1)/2=1,也是下标array[1]。
那倒数第一个下标非叶节点的下标是啥? 数组倒数第四个下标数是i=2,(i-1)/2=1,那么 下标array[0]就是第3个父节点。 数组倒数第三个下标数是i=1,(i-1)/2=1,也是下标array[0]。 此时还有吗? 数组倒数第五个下标数是i=0,(i-1)/2=-1,也是下标array[-1]。 也就是根节点没有父节点了…. 等等,我好像发现啥规律了… 父节点是array[2]=3 array[1]=7 array[0]=16。
array=[16,7,3,20,17,8] 现在要开始 XX联盟S17 的比赛,比赛组根据玩家投票新采用了一种新的比赛规则,规则如下: 横向:每个新晋擂主可以参与更高一级的比赛,直至选出冠军。登顶大根堆顶峰; 纵向:每个下台擂主要被更低一级的选手挑战,需要证明自己实力,也可能被一撸到底; 简言之:能者上,弱者下 每一小组选出最强者,参与擂主pk, 胜利者获取下一次挑战机会;失败者要被挑战,直至完成一场胜利,或者排名倒数 。 而后,开始了激烈的小组比赛,擂主 先把收拾自己的东西 ,因为他也不知道自己是一败涂地还是保持原位!心里有些忐忑~ 215. 数组中的第K个最大元素 兜兜转转,从第一篇博客到2021.08.22已经过去了2年半多了。
今天又回到这个题目。带来一种最小堆更加。