选择排序

来源:互联网 发布:java 反射 实例化单例 编辑:程序博客网 时间:2024/06/06 14:09

简单的选择排序

一趟简单选择排序就是通过n-I次关键字间的比较,从n-i+1个记录中选择关键字最小的记录,并和第I个记录交换。因此它的时间复杂度就是O(n2)。

树形选择排序

树形选择排序就是先对n个记录的关键字进行两两比较,然后在其中n/2个较小者之间再进行两两比较,如此重复,直至选出最小关键字的记录为止。这个过程可用一棵有n个叶子结点的完全二叉树表示。在选出最小的关键字之后,若想选出次小关键字,仅需将叶子结点中的最小关键字改为无穷值,然后从该叶子结点开始,修改到根路径上的各结点的关键字。
除了最小关键字之外,每选择一个次小关键字需要进行logn次比较,因此它的时间复杂度为O(nlogn),但此方法需要较多的辅助存储空间且和“最大值进行多余的比较“等缺点。

堆排序

将序列对应的一维数组看成一棵完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或均不小于)其左右孩子结点的值。由此,若序列是堆,则堆顶元素必为序列中n个元素的最小值(或最大值),即最小堆(最大堆)。若在输出堆顶的最小值之后,使得剩余n-1个元素的序列重新建成一个堆,则得到n个元素的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。
堆排序的代码如下

void HeapAdjust(HeapType &H,int s,int m){    rc = H.r[s];    for(j=2*s;j<=m;j*=2){        if(j<m&&LT(H.r[j].key,H.r[j+1].key)) ++j;        if(!LT(rc.key,H.r[j].key)) break;        H.r[s] = H.r[j];        s = j;    }    H.r[s] = rc;}void HeapSort(HeapType &H){    for(i=H.length/2;i>0;--i)        HeapAdjust(H,i,H.length);    for(i=H.length;i>1;--i){        H.r[1]←→H.r[i];        HeapAdjust(H,1,i-1);    }}

在深度为k的堆,筛选算法中进行的关键字比较次数至多为2(k-1)次,由于第i层上的节点数至多为2的i-1次方,以它们为根的二叉树的深度为h-i+1,则调用n/2次HeapAdjust的进行的关键字比较次数不超过4n。在调整建新堆时调用HeapAdjust过程n-1次,总共进行的比较次数不超过nlogn,所以时间复杂度为O(nlogn)。

0 0