堆排序与直接选择排序的比较

本文详细介绍了两种经典的排序算法——直接选择排序和堆排序。直接选择排序通过n-1次选择过程完成排序,而堆排序则利用了树形结构来优化比较过程,实现了更高效的排序效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接选择排序基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列.
直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作,时间复杂度为log(n2)。
堆排序可通过树形结构保存部分比较结果,可减少比较次数,时间复杂度为nlogn。

直接选择排序

#include<iostream> using namespace std; void StraightSelectSorting(int b[],int n) { for(int i=0; i<n-1; i++) { int k; int temp; k = i; //将k置值等于i for(int j=i+1; j<n; j++) { /*若存在比下标为k的元素的值小的元素, 用k(注意不是用i,这样循环计数更方便) 存取该元素下标 */ if(b[j] < b[k]) k = j; } if(i != k) { temp = b[i]; b[i] = b[k]; b[k] = temp; } } } int main() { int a[10] = {1,3,2,4,9,6,5,8,7,0}; StraightSelectSorting(a,10); for(int l=0; l<sizeof(a)/sizeof(int); l++) { cout<<a[l]<<" "; } cout<<endl; return 0; }

堆排序

#include<iostream> using namespace std; typedef int ElemType ; //该代码数组下标从0开始,从1开始的话要修改 void HeapAdjust(ElemType array[],int begin,int end) {/*array[begin...end]中,除array[begin]外,其他满足大根堆, 调整array[begin]使array[begin...end]成为一个大根堆 */ ElemType tempData;//暂存元素 tempData = array[begin]; for(int i=2*begin+1; i<=end; i=2*i+1) {/*每次调整,只有根可能不满足大根堆条件,将其与其孩子树的 根比较,向下筛选*/ if(i<end && array[i] < array[i+1])//注意i<end是正确的 i++;//找出要调整的根节点有较大根节点的孩子树 if(tempData >= array[i]) break;//已是大根堆,不用调整 /*否则,进行下面的交换,注意该交换不想其他排序的交换*/ array[begin] = array[i]; begin = i; /*用begin记录待插入元素的下标,以便下次array[begin] = array[i]; 或array[begin] = tempData;能正确插入*/ } array[begin] = tempData;//将备份元素插入begin的所指 } void HeapSort(ElemType a[],int n) { int j; ElemType temp; /*对还不是堆的元素[0...(n/2-1)]进行堆初始化*/ for( j=n/2-1; j>=0; j--) { HeapAdjust(a,j,n-1); } for(j=n-1; j>0; j--) { /*将大根堆的根调到最后一个*/ temp = a[0]; a[0] = a[j]; a[j] = temp; /*待排元素减一,对a[0...j-1]进行堆调整*/ HeapAdjust(a,0,j-1); } } int main() { ElemType ff[10] = {3,1,6,4,5,2,8,7,9,0}; HeapSort(ff,10); for(int k=0; k<sizeof(ff)/sizeof(ElemType); k++) { cout<<ff[k]<<" "; } cout<<endl; return 0; }

转载于:https://www.cnblogs.com/huangkq1989/archive/2010/07/15/2522664.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值