选择排序的基本思想是:每一趟(如第i趟)在后面n-i+1(i=1,2,……,n-1)个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到第n-1趟做完,待排序元素只剩下一个,就不用再选。
选择排序分为简单选择排序和堆排序。
一、简单选择排序
(1)简单选择排序的思想:假设排序表为L[1...n],第i趟排序即从L[i...n]中选择关键字最小的元素与L(i)交换,每一趟排序可以确定一个元素的最终位置,这样经过n-1趟排序就可以使得整个排序表有序。
(2)算法代码
(3)性能分析
空间效率:仅使用常数个辅助单元,所以空间效率为O(1).
时间效率:在简单选择排序的过程中,元素移动的操作次数很少,不超过3(n-1)次,最好情况的移动0次,此时对应的表已经有序;
但是元素间比较的次数与序列的初始状态无关,始终是n(n-1)/2次,因此时间复杂度是
O(n^2)。最好、最坏、平均情况下,时间复杂度都是O(n^2)。
稳定性:简单选择排序是不稳定的排序算法。
适用性:简单选择排序适用于顺序存储和链式存储的线性表,以及关键字较少的情况。
二、堆排序
(1)堆排序的思路:首先将存放在L[1...n]中的n个元素建成初始堆,堆顶元素(大根堆或小根堆)是最值元素,输出堆顶元素后,通常将堆底元素送入堆顶,此时根节点不再满足大根堆或小根堆的性质,堆被破坏,调整堆,将堆顶元素调整使得继续保持大根堆或小根堆的性质,再输出堆顶元素。如此重复,直到堆中仅剩下一个元素为止。
主要的两个步骤:建成初始堆和输出元素后调整堆。
可将堆视为一棵完全二叉树。
大根堆:完全二叉树中,根>=左、右;小根堆:完全二叉树中,根<=左、右。
一个结点每下坠一层,最多只需对比关键字2次,若树高为h,某节点在第i层,则将这个结点向下调整,最多只需要h-i层,关键字对比次数不超过2(h-i)。
(2)建立大根堆和调整
(3)输出堆顶元素后调整,把堆底元素换到堆顶,再调整。
如下所示,输出堆顶87,后调整。
(4)堆的插入操作
堆的插入,先将新节点放在堆的末端,再对这个新节点向上执行调整操作。如下所示,是大根堆中插入。
(5)算法实现
(6)性能分析
空间效率:仅使用常数个辅助单元,空间复杂度为O(1)。
时间效率:建堆时间为O(n),之后有n-1次向下调整操作,每次调整的时间复杂度为O(h)。
堆排序,在最好、最坏、平均情况下,时间复杂度都是O(nlog n)。注:log 以2为底。
稳定性:堆排序是一种不稳定的排序算法。
适用性:堆排序仅适用于顺序存储的线性表。