首页 > 编程知识 正文

选择算法,简单选择排序算法

时间:2023-05-04 17:26:29 阅读:141755 作者:585

选择排序算法有两种:直接选择排序和堆排序

1、直接选择排序(Straight Select Sort)算法思想:第一趟从n个元素的数据序列中选出关键字最小/大的元素并放在最前/后位置,下一趟从n-1个元素中选出最小/大的元素并放在最前/后位置。以此类推,经过n-1趟完成排序。

示例如下:

//排序publicstaticvoidselectsort (int [ ] a ) {int temp; for(intI=0; ia.length; I )//内层循环j=i 1,外层循环控制着循环次数。 也就是说,对于每一圈,a[i]的值是一圈的最小值。 在I位置为最小值for(intj=I1; ja.length; j () if ) a[I]a[j] ) {temp=a[i]; a[i]=a[j]; a[j]=temp; }}}} 2、堆排序:

堆排序涉及到完全二叉树的概念。堆是一个完全二叉树,分为大顶堆和小顶堆两种。

大顶堆:每个节点的值都大于或等于其左右孩子节点的值。如图(1)所示:

小顶堆:每个节点的值都小于或等于其左右孩子节点的值。如图(2)所示:

图(1)大顶堆图(2)小顶堆

堆排序算法的定义:

堆栈排序(Heap Sort )是利用堆进行排序的方法。 其基本思路是,将分类对象的序列构成一个大堆,此时序列整体的最大值是堆顶的根节点。 将其移除(实际上与堆数组的尾部元素进行交换,此时尾部元素为最大值),将剩下的N -1个元素重建为一个堆,即可得到n个元素中的下一个较小的值。 这样重复执行,最后得到有序的序列。

堆排序完整代码如下:

publicclasstestheapsort { publicstaticvoidmain (string [ ] args ) int [ ] arr={ 3,1,2,4,7,6,5,9,8,10 } hsssstatid for(inta:ARR ) System.out.print(a ) a ' ); (() ) ) ) ) ) ) 0000000000000000000000065 parent=0; parent----{maxheap(arr,parent,arr.length-1 ); }for(intt=ARR.Length-1; t0; t-- () swap(arr,0,t ); //要交换数据的最大帮助(arr,0,t-1 ); //根节点从0开始,继续构建高位。 }//交换数据的方法privatestaticvoidswap(int[]arr,int i,int t ) { int temp=arr[i]; arr[i]=arr[t]; arr[t]=temp; } /* *如何构建大堆* s表示节点,该节点具有左侧和右侧的子节点。 也就是说,此次调整位置的节点* m表示当前堆的长度*/privatestaticvoidmaxheap (int [ ] arr,int s,int m ) inttemp,j; temp=arr[s]; for(j=2*s1; j=m; j=2*j 1 ) {/j=2*s1是s节点左边的孩子,j 1是s节点右边的孩子//j=2*j 1是找到j的孩子节点if(JMARR[j]ARR[j1] ) j; 将//j设置为当前左右子节点中的较大值if(Temparr[j] ) break; 如果//s节点的值大于其最大子节点的值,则循环结束,此时不做任何改变,arr[s]=arr[j]; //否则,将大的子节点的值代入父节点s=j; 将//j的值代入s后,j成为下一个波的父节点,继续比较} arr[s]=temp; //循环结束} }最初构建大的山顶堆时,我们int parent = (arr.length-1)/2,即父节点从arr[4]=7开始,4、3、2、1、0都有子节点。

公式中,从最下层最右边的非终端节点开始构筑,与其子节点进行比较,根据需要进行交换。 每个非终端节点,实际上最多进行两次比较和交换操作。因此整个构建堆的时间复杂度为O(N)。

在正式排序时,获取第I次堆记录并重建堆需要o(logi )的时间(从具有完全二叉树的节点到根节点的距离为logi 1),并且需要n-1次堆记录,因此为http://www .

因此,总体上栈排序的时间复杂度为o(nlogn )。

重建堆的时间复杂度为O(nlogN)

从代码中可以看出:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。