常用排序算法之选择排序 ( 直接选择排序、堆排序 )
2010-10-06 20:19
330 查看
选择排序的方法是:每次从待排序的数据元素集合中选取关键字最小(或最大)的数据元素放到数据元素集合的最前(或最后),数据元素集合不断缩小,当数据元素集合为空时选择排序结束。常用的选择排序有直接选择排序和堆排序。
直接选择排序
方法:从待排序的数据元素集合中选取关键字最小的数据元素并将它与原始数据元素集合中的第一个数据元素交换位置;然后从不包括第一个位置上数据元素的集合选取关键字最小的数据元素并将它与原始数据元素集合中的第二个数据元素交换位置;如此重复,直到数据元素集合中中剩下一个数据元素为止。
C++实现:
SelectSort.cpp
时间复杂度:第1次排序要进行 n-1 次比较,第2次排序要进行 n-2 次比较,... ,第 n-1 次排序要进行1次比较,所以总的比较次数为:
比较次数 = (n-1) + (n-2) + ... + 1 = n(n-1)/2
在各次排序中,数据元素的移动次数最好为0次,最坏为3次。所以总的移动次数最好为0次,最坏为 3(n-1) 次。因此,直接选择排序算法的时间复杂度为 O(n^2) 。
空间复杂度为 O(1) 。
直接选择排序由于每次都要从无序记录区选出最小记录后,与无序区的第一个记录交换,而交换可能引起关键字相同的数据元素位置发生变化。所以它是不稳定的排序算法。如果在选出最小记录后,将它前面的无序记录依次后移,然后再将最小记录放在有序区的后面,这样就能保证排序算法的稳定性。
---------------------------------------------------------------------------------
堆排序
基本思想:在直接选择排序中,待排序的数据元素集合构成一个线性结构,要从有n个数据元素的线性表中选择出一个最小的数据元素需要比较n-1次。如果能把待排序的数据元素集合构成一个完全二叉树结构,而每次选择出一个最大(或最小)的数据元素只需比较完全二叉树的高度次,即 lbn 次,则排序算法的时间复杂度就是 O(n x lbn) 。
方法:构造一个最大堆并循环执行如下过程直到数组为空:
<1>. 把堆顶 a[0] 元素(为最大元素)和当前最大堆的最后一个元素交换。
<2>. 最大堆元素个数减 1 。
<3>. 由于第<1>步后根结点不再满足最大堆的定义,所以调整根结点使之满足最大堆的定义。
堆排充是一种不稳定的排序方法。
时间复杂度: O(n x lbn) 。
空间复杂度: O(1) 。
直接选择排序
方法:从待排序的数据元素集合中选取关键字最小的数据元素并将它与原始数据元素集合中的第一个数据元素交换位置;然后从不包括第一个位置上数据元素的集合选取关键字最小的数据元素并将它与原始数据元素集合中的第二个数据元素交换位置;如此重复,直到数据元素集合中中剩下一个数据元素为止。
C++实现:
SelectSort.cpp
void SelectSort( DataType a[], int n ) { int i, j, small; DataType temp; for ( i = 0; i < n -1; i ++ ) { small = i; for ( j = i +1; j < n; j ++ ) { if ( a[j].key < small.key ) small = j; } if ( small != i ) { temp = a[i]; a[i] = a[small]; a[small] = temp; } } }
时间复杂度:第1次排序要进行 n-1 次比较,第2次排序要进行 n-2 次比较,... ,第 n-1 次排序要进行1次比较,所以总的比较次数为:
比较次数 = (n-1) + (n-2) + ... + 1 = n(n-1)/2
在各次排序中,数据元素的移动次数最好为0次,最坏为3次。所以总的移动次数最好为0次,最坏为 3(n-1) 次。因此,直接选择排序算法的时间复杂度为 O(n^2) 。
空间复杂度为 O(1) 。
直接选择排序由于每次都要从无序记录区选出最小记录后,与无序区的第一个记录交换,而交换可能引起关键字相同的数据元素位置发生变化。所以它是不稳定的排序算法。如果在选出最小记录后,将它前面的无序记录依次后移,然后再将最小记录放在有序区的后面,这样就能保证排序算法的稳定性。
---------------------------------------------------------------------------------
堆排序
基本思想:在直接选择排序中,待排序的数据元素集合构成一个线性结构,要从有n个数据元素的线性表中选择出一个最小的数据元素需要比较n-1次。如果能把待排序的数据元素集合构成一个完全二叉树结构,而每次选择出一个最大(或最小)的数据元素只需比较完全二叉树的高度次,即 lbn 次,则排序算法的时间复杂度就是 O(n x lbn) 。
方法:构造一个最大堆并循环执行如下过程直到数组为空:
<1>. 把堆顶 a[0] 元素(为最大元素)和当前最大堆的最后一个元素交换。
<2>. 最大堆元素个数减 1 。
<3>. 由于第<1>步后根结点不再满足最大堆的定义,所以调整根结点使之满足最大堆的定义。
堆排充是一种不稳定的排序方法。
时间复杂度: O(n x lbn) 。
空间复杂度: O(1) 。
相关文章推荐
- 算法分析-选择排序(直接选择排序 & 堆排序)
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序,堆排序)
- 选择排序(直接选择排序、堆排序)
- 2.选择排序(直接选择排序和堆排序)
- 选择排序:直接选择排序,堆排序
- 数据结构 JAVA描述(十一) 选择排序(直接选择排序,树形选择排序,堆排序)
- 排序大全【各种排序】:直接插入,折半插入,冒泡,快排,简单选择,堆排序,归并排序
- java中各种常用排序实现(直接插入排序、直接选择排序、堆排序、冒泡排序、快速排序和归并排序)
- 2.选择排序:直接选择排序和堆排序
- 选择排序 (直接选择排序 ,堆排序)
- C语言常用排序——直接插入,冒泡,选择,希尔,快速,堆排序
- 选择排序----直接选择排序与堆排序
- 算法 排序算法之选择排序--直接选择排序和堆排序
- 七种排序(直接插入、折半插入、希尔、起泡、快速、简单选择、堆排序)
- 选择排序算法---直接选择排序和堆排序
- 排序算法: 冒泡排序, 快速排序,希尔排序,直接插入排序 ,直接选择排序,归并排序,堆排序
- java进阶- 经典排序(插入排序、冒泡排序、快排(分划交换排序)、直接选择排序、堆排序、合并排序)
- 七种排序(直接插入、折半插入、希尔、起泡、快速、简单选择、堆排序)
- 内部排序之选择排序(直接选择排序,堆排序)
- 六、内部排序综合(九种)—插入类排序(直接插入、折半插入、希尔排序);交换类排序(冒泡、快速);选择类排序(简单选择、堆排序);二路归并排序;基数排序