List::sort排序

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; //确定归并后区间的(新)起点
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章