课程笔记 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;
}
先来看起泡排序的一般版本:
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;
}
相关文章推荐
- STL中map的数据结构
- C++容器&数据结构
- 数据结构实验之栈二:一般算术表达式转换成后缀式
- 数据结构概述
- linux内核数据结构之kfifo
- 南阳oj 数据结构 括号配对 题目2 NYOJ
- 暑假集训-数据结构
- 数据结构和设计模式02(树,图)
- 算法概述
- JSON 数据结构介绍
- XML数据结构 SAX 解析
- 数据结构与算法(3 Reverse链表)
- 初学数据结构之堆栈
- 数据结构二叉树
- Java数据结构-线性表之链表应用-检测链表是否有环
- 南阳oj NYoj 数据结构 士兵杀敌(一) 题目108
- Java数据结构-线性表之单链表应用-单链表合并
- Java数据结构-线性表之单链表应用-重复节点的删除
- Java数据结构-线性表之单链表应用-单链表的逆置
- Java数据结构-线性表之静态链表