template <typename T> void List<T>::sort(ListNodePosi(T) p, int n) { //列表区间排序
switch (rand() % 3) { //随机选取排序算法。可根据具体问题的特点灵活选取或扩充
case 1: insertionSort(p, n); break; //插入排序
case 2: selectionSort(p, n); break; //选择排序
default: mergeSort(p, n); break; //归并排序
}
}
先来看看有序列表查找算法:
template <typename T> //在有序列表内节点p(可能是trailer)的n个(真)前驱中,找到不大于e的最后者
ListNodePosi(T) List<T>::search(T const& e, int n, ListNodePosi(T) p) const {
// assert: 0 <= n <= rank(p) < _size
/*DSA*/printf("searching for "); print(e); printf(" :\n");
while (0 <= n--) //对于p的最近的n个前驱,从右向左逐个比较
/*DSA*/{ printf(" <%4d>", p->pred->data);
if (((p = p->pred)->data) <= e) break; //直至命中、数值越界或范围越界
/*DSA*/} printf("\n");
// assert: 至此位置p必符合输出语义约定——尽管此前最后一次关键码比较可能没有意义(等效于与-inf比较)
return p; //返回查找终止的位置
} //失败时,返回区间左边界的前驱(可能是header)——调用者可通过valid()判断成功与否
插入排序
template <typename T> //列表的插入排序算法:对起始于位置p的n个元素排序
void List<T>::insertionSort(ListNodePosi(T) p, int n) { //valid(p) && rank(p) + n <= size
/*DSA*/printf("InsertionSort ...\n");
for (int r = 0; r < n; r++) { //逐一为各节点
insertAfter(search(p->data, r, p), p->data); //查找适当的位置并插入
p = p->succ; remove(p->pred); //转向下一节点
}
}
先来看看列表找最大结点的算法:
template <typename T> static bool lt(T & a, T & b) { return a < b; } //less than
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; //返回最大节点位置
}
选择排序:
template <typename T> //列表的选择排序算法:对起始于位置p的n个元素排序
void List<T>::selectionSort(ListNodePosi(T) p, int n) { //valid(p) && rank(p) + n <= size
/*DSA*/printf("SelectionSort ...\n");
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); //找出最大者(歧义时后者优先)
insertBefore(tail, remove(max)); //将其移至无序区间末尾(作为有序区间新的首元素)
tail = tail->pred; n--;
}
}
List归并排序:
template <typename T> //有序列表的归并:当前列表中自p起的n个元素,与列表L中自q起的m个元素归并
void List<T>::merge(ListNodePosi(T)& p, int n, List<T>& L, ListNodePosi(T) q, int m) {
// assert: this.valid(p) && rank(p) + n <= size && this.sorted(p, n)
// L.valid(q) && rank(q) + m <= L._size && L.sorted(q, m)
// 注意:在归并排序之类的场合,有可能 this == L && rank(p) + n = rank(q)
ListNodePosi(T) pp = p->pred; //借助前驱(可能是header),以便返回前 ...
while (0 < m) //在q尚未移出区间之前
if ((0 < n) && (p->data <= q->data)) //若p仍在区间内且v(p) <= v(q),则
{ if (q == (p = p->succ)) break; n--; } //将p替换为其直接后继(等效于将p归入合并的列表)
else //若p已超出右界或v(q) < v(p),则
{ insertBefore(p, L.remove((q = q->succ)->pred)); m--; } //将q转移至p之前
p = pp->succ; //确定归并后区间的(新)起点
}
原文地址:http://blog.csdn.net/ganxiang2011/article/details/46235265