选择排序

来源:互联网 发布:淘宝最好的沉香卖家 编辑:程序博客网 时间:2024/06/04 23:33

代码来源:《数据结构(c++语言版)(第三版)》,邓俊辉编著,ISBN: 978-7-302-33064-6


选择排序(selectionsort)适用于向量和列表的结构。向量中的起泡排序(bubblesort)就是一种选择排序。


选择排序的思想是,在序列中,从乱序中找到最大元素,将其移送至有序队列的开头,即作为首元素插入前缀。代码如下:


template <typename T> //列表的选择排序算法:对起始于位置p的n个元素排序void List<T>::selectionSort ( ListNodePosi(T) p, int n ) { //valid(p) && rank(p) + n <= size   ListNodePosi(T) head = p->pred; ListNodePosi(T) tail = p;   for ( int i = 0; i < n; i++ ) tail = tail->succ; //待排序区间为(head, tail)   while ( 1 < n ) { //在至少还剩两个节点之前,在待排序区间内      ListNodePosi(T) max = selectMax ( head->succ, n ); //找出最大者(歧义时后者优先)      insertB ( tail, remove ( max ) ); //将其移至无序区间末尾(作为有序区间新的首元素)      tail = tail->pred; n--;   }}

其中,反复迭代selectMax函数找到最大值,并将其一直有序队列开头。但其中用到insertB和remove函数,这两个函数都需要用到动态数据分配,这样会极大的降低效率,一般都会避免这一算法。不如改进为交换元素。

selectMax函数如下:

template <typename T> //从起始于位置p的n个元素中选出最大者ListNodePosi(T) List<T>::selectMax ( ListNodePosi(T) p, int n ) {   ListNodePosi(T) max = p; //最大者暂定为首节点p   for ( ListNodePosi(T) cur = p; 1 < n; n-- ) //从首节点p出发,将后续节点逐一与max比较      if ( !lt ( ( cur = cur->succ )->data, max->data ) ) //若当前元素不小于max,则         max = cur; //更新最大元素位置记录   return max; //返回最大节点位置}

从首节点出发,将后续节点逐一与max比较。其中比较器使用的是不小于,这样保证选择的是最后位置的最大值,在移动数据时减少开销。这一算法也被称作painter's Algorithm,因为它选择的往往是最后一个元素,正如画家画油画一样,显示出的往往是最后一次绘画的颜色。


这一算法的最坏复杂度是Θ(n^2),也就是没有最好和最坏情况,所有情况都是n^2。看似与bubblesort没有区别,但是在比较和移动过程中总是会比起泡排序有优化。在以后会学习到,借助更高级的数据结构,selectMax算法的复杂度可降至O(logn)。

0 0
原创粉丝点击