在前面介绍完Vector向量类的实现后,在此处简要介绍三个排序算法的实现,其中包括代码以及图示例。
1>下面首先介绍选择排序。选择排序是选定首端或者末端作为遍历开端,此处假定选定末端。在一次从后往前遍历的过程中,在指针指向元素的前方,选出其中最大的一个值,与指针指向的元素交换。每一次交换都保证最大值排在此指针上次元素的后面。具体代码如下所示。
template <typename T>
void Vector<T>::selectSort(Rank lo, Rank hi) //选择排序
{
while (lo < --hi) //这里并没有将hi列出排序中
{
swap(_elem[max(lo, hi)], _elem[hi]); //将hi与【lo,hi】中的最大值交换
}
}
template<typename T>
Rank Vector<T>::max(Rank lo, Rank hi) //选出范围最大值
{
Rank mx = hi; //记录一下范围末位元素
while (lo < hi--)
{
if (_elem[hi]>_elem[mx]) //一次遍历找出最大值
mx = hi;
}
return mx; //返回最大值的秩,即下标
}
只看代码没有感性的认识,下面附上一张选择排序的示例图。
主要步骤是选出指针指向元素前方的最大值与指针指向元素交换,在经过一轮的遍历以后,这个区间的元素就是从小到大排好序的了。
2> 下面介绍一下冒泡排序。冒泡排序的主要思想是:如果相邻两个元素局部无序,那么将两个元素交换,形成局部有序。在第一遍扫描的时候,将最大值置于最后一个位置。在第二遍扫描的时候,将仅次于最大值的值置于倒数第二个位置,以此类推,故名冒泡排序。具体代码如下所示。
template<typename T>
void Vector<T>::bubbleSort(Rank lo, Rank hi) //冒泡排序
{
while (!bubble(lo, hi--));
}
注:bubble方法返回的是bool值,这个值代表着这个向量是不是已经排好序。
下面贴出bubble方法的代码。
template<typename T>
bool Vector<T>::bubble(Rank lo, Rank hi)
{
bool sorted = true;
while (++lo < hi)
{
if (_elem[lo - 1]>_elem[lo])
{
sorted = fasle;
swap(_elem[lo - 1], _elem[lo]); //交换两个值
}
}
return sorted;
}
注:此方法只是检测相邻两个元素的是不是有序。
下面贴出冒泡排序的示意图。
注:图示的解析已经比较清楚,故不再做进一步介绍。
3>下面介绍一下归并排序。归并排序,顾名思义也是将散的元素组合到一起,主要思想是:首先将元素较平均的分成两堆,然后递归的将这个两堆分别在分成两堆,在最后分到每组最多只剩下两个元素的时候,开始整合。整合主要实现是将两个组中的队首元素抽出来,比较两个值的大小,将小的值拿出来,放到第一位,以此类推,最后实现整个向量元素的排序。具体代码如下所示。
template<typename T>
void Vector<T>::mergeSort(Rank lo, Rank hi)
{
if (hi - lo < 2)
return;
int mi = (lo + hi) >> 1;
mergeSort(lo, mi);
mergeSort(mi, hi);
merge(lo, mi, hi);
}
注:此处使用递归将向量均分。
下面给出merge方法代码。
template<typename T>
void Vector<T>::merge(Rank lo, Rank mi, Rank hi)
{
T* A = _elem + lo; //将指针前移lo位,指向lo元素的内存空间
int lb = mi - lo; //记录前部分的元素数值
t* B = new T[lb]; //创建新数组,存放前部分元素
for (Rank i = 0; i < lb; B[i] = A[i++]); //实现B[i]=A[i]
int lc = hi - mi; //记录后部分数组总数
T* C = _elem + mi; //指针前移mi位,指向mi元素的内存空间
for (Rank i = 0, j = 0, k = 0; (j < lb) || (k < lc);)
{
if ((j < lb) && (!(k < lc) || (B[j] <= C[k])))
A[i++] = B[j++]; //此处更改了内部数组,实现排序
if ((k < lc) && (!(j < lb) || (C[k] < B[j])))
A[i++] = C[k++];
}
delete[] B;
}
下面给出归并排序的示例图,稍微有点乱,后期再进行更改吧。
经过这么几次的画图与查询资料,自己收获了很多。在以后的学习生涯中,应该持着仔细的态度,认真钻研每一个问题,任何一个自己没有懂的小点,里面可能涉及到很多知识。尤其在指针这一块,以后该继续加强喽。