template <typename T> void Vector<T>::sort(Rank lo, Rank hi) { //向量区间[lo, hi)排序
switch (rand() % 5) { //随机选取排序算法。可根据具体问题的特点灵活选取或扩充
case 1: bubbleSort(lo, hi); break; //起泡排序
case 2: selectionSort(lo, hi); break; //选择排序(习题)
case 3: mergeSort(lo, hi); break; //归并排序
case 4: heapSort(lo, hi); break; //堆排序(稍后介绍)
default: quickSort(lo, hi); break; //快速排序(稍后介绍)
}
/*DSA*/ //selectionSort(lo, hi);
}
起泡排序 bubbleSort(lo, hi):
template <typename T> //向量的起泡排序
void Vector<T>::bubbleSort(Rank lo, Rank hi) //assert: 0 <= lo < hi <= size
{ while (!bubble(lo, hi--)); } //逐趟做扫描交换,直至全序
template <typename T> bool Vector<T>::bubble(Rank lo, Rank hi) { //一趟扫描交换
bool sorted = true; //整体有序标志
while (++lo < hi) //自左向右,逐一检查各对相邻元素
if (_elem[lo - 1] > _elem[lo]) { //若逆序,则
sorted = false; //意味着尚未整体有序,并需要
swap(_elem[lo - 1], _elem[lo]); //通过交换使局部有序
}
return sorted; //返回有序标志
}
选择排序selectionSort(lo, hi):
template <typename T>
Rank Vector<T>::max(Rank lo, Rank hi) { //在[lo, hi]内找出最大者
Rank mx = hi;
while (lo < hi--) //逆向扫描
if (_elem[hi] > _elem[mx]) //且严格比较
mx = hi; //故能在max有多个时保证后者优先,进而保证selectionSort稳定
return mx;
}
template <typename T> //向量选择排序
void Vector<T>::selectionSort(Rank lo, Rank hi) { //assert: 0 < lo <= hi <= size
/*DSA*/printf("\tSELECTIONsort [%3d, %3d)\n", lo, hi);
while (lo < --hi)
swap(_elem[max(lo, hi)], _elem[hi]); //将[hi]与[lo, hi]中的最大者交换
}
归并排序 mergeSort(lo, hi):
template <typename T> //向量归并排序
void Vector<T>::mergeSort(Rank lo, Rank hi) { //0 <= lo < hi <= size
/*DSA*/printf("\tMERGEsort [%3d, %3d)\n", lo ,hi);
if (hi - lo < 2) return; //单元素区间自然有序,否则...
int mi = (lo + hi) >> 1; //以中点为界
mergeSort(lo, mi); mergeSort(mi, hi); merge(lo, mi, hi); //分别对前、后半段排序,然后归并
}
template <typename T> //有序向量的归并
void Vector<T>::merge(Rank lo, Rank mi, Rank hi) { //以mi为界、各自有序的子向量[lo, mi)和[mi, hi)
T* A = _elem + lo; //合并后的向量A[0, hi - lo) = _elem[lo, hi)
int lb = mi - lo; T* B = new T[lb]; //前子向量B[0, lb) = _elem[lo, mi)
for (Rank i = 0; i < lb; B[i] = A[i++]); //复制前子向量
int lc = hi - mi; T* C = _elem + mi; //后子向量C[0, lc) = _elem[mi, hi)
for (Rank i = 0, j = 0, k = 0; (j < lb) || (k < lc); ) { //将B[j]和C[k]中的小者续至A末尾
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; //释放临时空间B
} //归并后得到完整的有序向量[lo, hi)
堆排序heapSort(lo, hi):
template <typename T> void Vector<T>::heapSort(Rank lo, Rank hi) { //0 <= lo < hi <= size
/*DSA*/printf("\tHEAPsort [%3d, %3d)\n", lo, hi);
PQ_ComplHeap<T> H(_elem, lo, hi); //取出待排序区间并建成完全二叉堆,O(n)
while (!H.empty()) //反复迭代,直至堆空
_elem[--hi] = H.delMax(); //摘除最大元并转移至原区间:等效于堆顶与末元素对换后下滤
}
template <typename T> T PQ_ComplHeap<T>::delMax() { //删除非空完全二叉堆中优先级最高的词条
T maxElem = _elem[0]; _elem[0] = remove(_size - 1); //摘除堆顶(首词条),代之以末词条
percolateDown(_size, 0); //对新堆顶实施下滤调整
return maxElem; //返回此前备份的最大词条
}
快速排序quickSort(lo, hi):
template <typename T> //向量快速排序
void Vector<T>::quickSort(Rank lo, Rank hi) { //0 <= lo < hi <= size
/*DSA*/printf("\tQUICKsort [%3d, %3d)\n", lo, hi);
if (hi - lo < 2) return; //单元素区间自然有序,否则...
Rank mi = partition(lo, hi - 1); //在[lo, hi - 1]内构造轴点
quickSort(lo, mi); //对前缀递归排序
quickSort(mi + 1, hi); //对后缀递归排序
}
template <typename T> //轴点构造算法:通过调整元素位置构造区间[lo, hi]的轴点,并返回其秩
Rank Vector<T>::partition(Rank lo, Rank hi) { //版本B:可优化处理多个关键码雷同的退化情况
swap(_elem[lo], _elem[lo + rand() % (hi - lo + 1)]); //任选一个元素与首元素交换
T pivot = _elem[lo]; //以首元素为候选轴点——经以上交换,等效于随机选取
while (lo < hi) { //从向量的两端交替地向中间扫描
while (lo < hi)
if (pivot < _elem[hi]) //在大于pivot的前提下
hi--; //向左拓展右端子向量
else //直至遇到不大于pivot者
{ _elem[lo++] = _elem[hi]; break; } //将其归入左端子向量
while (lo < hi)
if (_elem[lo] < pivot) //在小于pivot的前提下
lo++; //向右拓展左端子向量
else //直至遇到不小于pivot者
{ _elem[hi--] = _elem[lo]; break; } //将其归入右端子向量
} //assert: lo == hi
_elem[lo] = pivot; //将备份的轴点记录置于前、后子向量之间
return lo; //返回轴点的秩
}