808|知识总结|选择排序

本文详细介绍了选择排序(包括简单选择排序和堆排序)的基本思想、分类、实现算法以及时间复杂度和空间复杂度。特别强调了堆排序的特点,如大根堆和小根堆,以及其在关键字较多情况下的适用性。还涉及了堆的插入和删除操作以及相关习题解析。
摘要由CSDN通过智能技术生成

一、选择排序

(1)基本思想:每一趟从无序区的关键字中选择最小的元素放在有序区的最后,直到全部元素排列完成。

(2)分类:简单选择排序、堆排序。

1.简单选择排序

(1)基本思想:在第i趟排序开始,从无序区R[i,...,n-1]中对比选出最小的元素,与无序区第一个元素R[i]交换位置,使R[0,...,i]成为新的有序区。

(2)注意:简单选择排序每趟产生的有序区都是全局有序,也就是说有序区的所有元素都已归位。

(3)算法

void Selectsort(Elemtype R[],int n)
{
    int i,j,k;
    for(i=0;i<n-1;i++)    //R[n-1]是最后一个元素不需要比较肯定是最大的
    {
       k=i;
       for(j=i+1;j<n;j++)
          if(R[j].key<R[k].key)
            k=j;
       if(k!=i)
         swap(R[i],R[k]);  //交换所有,而不是key
     }
}

(4)算法分析

空间复杂度:O(1)

时间复杂度:O(n²)

不稳定的算法:相同元素的相对位置会发生改变。

2.堆排序

(1)定义:

堆排序——一种树形选择排序,特点是将序列看做一棵完全二叉树的顺序存储结构。

堆——当一个序列R[1,...,n-1]满足Ki>=K2i && Ki>=K2i+1是大根堆;Ki<=K2i && Ki<=K2i+1是小根堆。

(2)注意:简单选择排序每趟产生的有序区都是全局有序,也就是说有序区的所有元素都已归位。

(3)算法

void sift(Elemtype R[],int low,int high)
{
    int i=low;
    int j=2*i;
    Elemtype tmp=R[i];
    while(j<high)
    {
          if(j<high && R[j].key<R[j+1])  //比较左右孩子谁大,再与父节点比较
            j++;
          if(R[j].key>tmp.key)
          {
             R[i]=R[j];    //没有交换,只是覆盖,所以需要tmp
             i=j;          //原父节点的位置改变,观察是否继续“下坠”
             j=2*i;
          } 
          else
              break;
     
    }
    R[i]=tmp;
}

void HeapSort(Elemtype R[],int n)
{
    int i;
    for(i=n/2;i>=1;i--)
       sift(R,i,n);     //建立初始堆,把乱序变为有序,之后的操作由于根节点发生了交换只需要下坠根节点即可
    for(i=n;i>=1;i--)
    {
        swap(R[1],R[i]);   //最大值永远是R[1],与最后一个节点交换,从小到大排序
        sift(R,1,i-1);   //对R[1,...,i-1]进行筛选
    }
}

(4)算法分析

空间复杂度:O(1)

时间复杂度:O(nlog2n)

建堆时间复杂度:O(n)

调整时间复杂度:O(h)

不稳定排序算法。

适用性:关键字较多的情况

(5)堆的插入和删除

插入:将新元素插入到表尾,与父节点依次比较,若新元素比父节点大(大根堆)则交换,一路“上升”。

删除:删除某元素,将表尾元素补在空中,再与左右子树比较,一路“下坠”,直到到达位置。

下坠:每一层关键字对比2次:左右子树对比+父节点与大子树对比

二、习题总结

1.李春葆例题

2.王道选择题

(1)堆中次大值一定在根的下一层,因为所有子树都是堆。

(2)具有n个节点的堆中插入或删除一个新元素的时间复杂度为O(log2n),因为需要向上或向下变动O(h)

(3)与基数排序有关:【不明白】

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值