有序列表 & 排序器

有序列表

若列表中所有节点的逻辑次序与其大小次序完全一致,则称作有序列表。

唯一化

template <typename T> int List<T>::uniquify() { //成批剔除重复元素,效率更高if ( _size < 2 ) return 0; //平凡列表自然无重复int oldSize = _size; //记录原规模ListNodePosi(T) p = first(); ListNodePosi(T) q; //p为各区段起点,q为其后继while ( trailer != ( q = p->succ ) ) //反复考查紧邻的节点对(p, q)if ( p->data != q->data ) p = q; //若互异,则转向下一区段else remove ( q ); //否则(雷同),删除后者return oldSize - _size; //列表规模变化量,即被删除元素总数
}

查找

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" );do {p = p->pred; n--;  //从右向左/*DSA*/  printf ( " -->%4d", p->data );} while ( ( -1 < n ) && ( e < p->data ) ); //逐个比较,直至命中或越界/*DSA*/  printf ( "\n" );return p; //返回查找终止的位置
} //失败时,返回区间左边界的前驱(可能是header)——调用者可通过valid()判断成功与否

排序器

统一入口

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的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++ ) { //逐一为各节点insertA ( search ( p->data, r, p ), p->data ); //查找适当的位置并插入p = p->succ; remove ( p->pred ); //转向下一节点}
}

选择排序


示例程序

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 ); //找出最大者(歧义时后者优先)insertB ( tail, remove ( max ) ); //将其移至无序区间末尾(作为有序区间新的首元素)/*DSA*///swap(tail->pred->data, selectMax( head->succ, n )->data );tail = tail->pred; n--;}
}
template <typename T> //从起始于位置p的n个元素中选出最大者
ListNodePosi(T) List<T>::selectMax ( ListNodePosi(T) p, int n ) {ListNodePosi(T) max = p; //最大者暂定为首节点pfor ( 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个元素,与列表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归入合并的列表,并替换为其直接后继else //若p已超出右界或v(q) < v(p),则{ insertB ( p, L.remove ( ( q = q->succ )->pred ) ); m--; } //将q转移至p之前p = pp->succ; //确定归并后区间的(新)起点
}

分治策略

template <typename T> //列表的归并排序算法:对起始于位置p的n个元素排序
void List<T>::mergeSort ( ListNodePosi(T) & p, int n ) { //valid(p) && rank(p) + n <= size/*DSA*///printf ( "\tMERGEsort [%3d]\n", n );if ( n < 2 ) return; //若待排序范围已足够小,则直接返回;否则...int m = n >> 1; //以中点为界ListNodePosi(T) q = p; for ( int i = 0; i < m; i++ ) q = q->succ; //均分列表mergeSort ( p, m ); mergeSort ( q, n - m ); //对前、后子列表分别排序merge ( p, m, *this, q, n - m ); //归并
} //注意:排序后,p依然指向归并后区间的(新)起点

最后两个表示该没有明白,艹~~~.

数据结构 (C++)笔记6 (有序列表 排序器)相关推荐

  1. html和css有序列表,HTMLCSS基础学习笔记14—有序列表及列表嵌套

    我们上篇讲到了无序列表,那么今天就来看看有序列表和他们的组合嵌套使用吧. 有序列表 现在我们要做那堆杂事了,但是发现这么多杂事,先做哪个好呢?于是我们给这堆杂事弄个优先级排序,让我们能够按照顺序做下去 ...

  2. 数据结构学习笔记(Ⅷ):排序

    目录 1 排序基础 1.1 排序的基本概念 2 排序算法 2.1 插入排序 1.思想 2.实现 3.效率分析 4.优化 2.2 希尔排序 1.定义 2.实现 3.效率分析 3 交换排序 3.1 冒泡排 ...

  3. Python数据结构与算法笔记(四):排序问题——列表排序

    排序 常见的排序算法: 列表排序Low三人组 冒泡排序,选择排序,插入排序 冒泡排序 原始数据. 将7和5进行比较,若7大于5,则交换. 8比7大,不进行交换,接下来看8.用8跟2进行比较. 最后,就 ...

  4. 数据结构学习(列表:五(有序列表的排序算法))

    有序列表 选择排序 选择排序算法将有序列表的分为无序前缀和有序后缀两部分,此外,还要求不大于后缀,如此,只需要从前缀中挑出最大者,并作为最小元素转入后缀中,即可使有序部分的范围不断扩张.这个算法的不变 ...

  5. 列表排序并返回索引_Python成为专业人士笔记–List列表

    专业人士笔记"系列目录: 创帆云:Python成为专业人士笔记--强烈建议收藏!每日持续更新!​zhuanlan.zhihu.com Python列表是Python程序中广泛使用的一种通用数 ...

  6. 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 21

    大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 211 第 ...

  7. C++及数据结构复习笔记(十二)(列表)

    2.2 列表 向量结构中,各数据的物理存放位置与逻辑次序完全对应,故可通过秩直接访问对应的元素,这称为循秩访问.为保证对列表元素访问的可行性,逻辑上互为前驱和后继的元素之间,应维护某种索引关系.这种索 ...

  8. Python数据结构学习笔记——链表:无序链表和有序链表

    目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...

  9. C++ 数据结构(三)列表(3)有序列表

    来源:我的博客站 OceanicKang |<C++ 数据结构(三)列表(3)有序列表> 上一篇:<C++ 数据结构(三)列表(2)无序列表> 唯一化 template < ...

最新文章

  1. html5用圆圈画猫,html5的应用-画一个可爱的小猫咪效果图
  2. Windows在当前目录(文件)打开cmd窗口
  3. 技术交流:老刘说NLP技术公众号开通
  4. python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog)
  5. 数据结构链表例程_如何掌握RxJava例程的四个结构
  6. Linux 进程号 端口号 互找
  7. html缩放排版乱了_交作业 | 代码排版逐行显现效果
  8. Layout自动布局(2)-手写代码
  9. JPG图片转换成Word文字教程分享
  10. 2021-02-14金蝶KIS旗舰版从采购订单下推外购入库单使用说明,金蝶盘点机PDA仓库条码管理
  11. ubuntu下安裝搜狗輸入法
  12. python上方菜单栏不见了如何恢复_word菜单栏不见了,如何恢复
  13. transition 属性
  14. mac原生壁纸,拿走不谢!
  15. 【实战记录分析】目录导航
  16. eax,ebx,ecx,edx,esi,edi,ebp,esp寄存器的作用
  17. Soft Labels for Ordinal Regression阅读笔记
  18. 阿里云短信 签名 模板编写
  19. Raspberry/Ubuntu 20.04命令行连接eap-gtc企业wifi
  20. HashSet里的元素是不能重复的,那用什么方法来区分重复与否呢?

热门文章

  1. 【Kawasaki川崎机器人码垛程序】CP180L-AC01
  2. 2022金三银四前端面试题预告
  3. Flask03_路由传参
  4. 我们应该怎样做需求分析?(一)需求调研
  5. inventor如何钣金出弧面_Inventor钣金设计教程
  6. 接口隔离原则(Interface Segregation Principle)
  7. C++位运算:与,或,非( , | , !)
  8. 人工智能的发展历程,AI ,路在何方(文章分享)
  9. IPaddr和IPaddr2的区别
  10. 求助,电脑关闭游戏后自动弹出dptf