您的位置:首页 > 理论基础 > 数据结构算法

课程笔记 05:数据结构(清华) 向量-排序

2015-07-20 19:21 281 查看
/*--起泡排序--*/

先来看起泡排序的一般版本:

template <typename T>

void vector::BubbleSort(Rank lo, Rank hi) //算法框架

{ while ( !bubble(lo, hi--) ); } //逐趟做扫描交换

bool vector::bubble(Ranklo, Rank hi) //单趟扫描交换

{

bool sorted = true; //整体有序标志

while (++ lo < hi)

if (_elem[lo - 1] > _elem[lo])

{

sorted = false; //标记为逆序状态

swap(_elem[lo], _elem[lo - 1]); //交换乱序对

}

return sorted; //返回有序标记

}

假若乱序对仅存在于向量的前方项时,则完全可以通过标记最后端的乱序项来减少扫描的数目,从而提高效率,其实现如下:

void vector::BubbleSort(Rank lo, Rank hi) //算法框架

{ while ( lo < (hi = bubble(lo, hi))); } //逐趟做扫描交换

bool vector::bubble(Ranklo, Rank hi) //单趟扫描交换

{

bool last = hi; //最末逆序项

while (++ lo < hi)

if (_elem[lo - 1] > _elem[lo])

{

last = lo; //标记为最末逆序项

swap(_elem[lo], _elem[lo - 1]); //交换乱序对

}

return last; //返回最末逆序项

}

如此一来,就可以在每趟的扫描中出现有序尾项后减少后续的扫描量,因此使得许多实例的处理效率大有提高。

/*--归并排序--*/

我们考察两段长度分别为m, n 的有序向量时,发现若将其合并成一段,则所用时间为O(m+n)。若我们逆向思考,将一个长度为n的向量连续二分,则经过logn次的归并就可以完成排序了。如此一来,整个向量的排序时间为O(nlogn)。

template <typename T>

void vector::mergesort(Rank lo, Rank hi) //算法框架

{

Rank mi = (lo + hi) / 2;

if ( mi ) return; //设置递归基

mergesort(lo, mi); //深入前段排序

mergesort(mi, hi); //深入后端排序

merge(lo, mi, hi); //二路并归

}

void vector::merge(Rank lo, Rank mi, Rank hi) //主体部分

{

T & A = new T[mi - lo];

A = _elem[lo];

int la = mi - lo, lb = hi - mi;

int i = 0, j =0, k = 0;

while ( i < la )

{

if (j <= lb || A[i] <= _elem[j + mi])

_elem[k ++] = A[i ++];

else

_elem[k ++] = _elem[mi + j ++];

}

delete [] A;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: