数据结构 (C++)笔记6 (有序列表 排序器)
有序列表 & 排序器
有序列表
若列表中所有节点的逻辑次序与其大小次序完全一致,则称作有序列表。
唯一化
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 (有序列表 排序器)相关推荐
- html和css有序列表,HTMLCSS基础学习笔记14—有序列表及列表嵌套
我们上篇讲到了无序列表,那么今天就来看看有序列表和他们的组合嵌套使用吧. 有序列表 现在我们要做那堆杂事了,但是发现这么多杂事,先做哪个好呢?于是我们给这堆杂事弄个优先级排序,让我们能够按照顺序做下去 ...
- 数据结构学习笔记(Ⅷ):排序
目录 1 排序基础 1.1 排序的基本概念 2 排序算法 2.1 插入排序 1.思想 2.实现 3.效率分析 4.优化 2.2 希尔排序 1.定义 2.实现 3.效率分析 3 交换排序 3.1 冒泡排 ...
- Python数据结构与算法笔记(四):排序问题——列表排序
排序 常见的排序算法: 列表排序Low三人组 冒泡排序,选择排序,插入排序 冒泡排序 原始数据. 将7和5进行比较,若7大于5,则交换. 8比7大,不进行交换,接下来看8.用8跟2进行比较. 最后,就 ...
- 数据结构学习(列表:五(有序列表的排序算法))
有序列表 选择排序 选择排序算法将有序列表的分为无序前缀和有序后缀两部分,此外,还要求不大于后缀,如此,只需要从前缀中挑出最大者,并作为最小元素转入后缀中,即可使有序部分的范围不断扩张.这个算法的不变 ...
- 列表排序并返回索引_Python成为专业人士笔记–List列表
专业人士笔记"系列目录: 创帆云:Python成为专业人士笔记--强烈建议收藏!每日持续更新!zhuanlan.zhihu.com Python列表是Python程序中广泛使用的一种通用数 ...
- 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第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 第 ...
- C++及数据结构复习笔记(十二)(列表)
2.2 列表 向量结构中,各数据的物理存放位置与逻辑次序完全对应,故可通过秩直接访问对应的元素,这称为循秩访问.为保证对列表元素访问的可行性,逻辑上互为前驱和后继的元素之间,应维护某种索引关系.这种索 ...
- Python数据结构学习笔记——链表:无序链表和有序链表
目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...
- C++ 数据结构(三)列表(3)有序列表
来源:我的博客站 OceanicKang |<C++ 数据结构(三)列表(3)有序列表> 上一篇:<C++ 数据结构(三)列表(2)无序列表> 唯一化 template < ...
最新文章
- html5用圆圈画猫,html5的应用-画一个可爱的小猫咪效果图
- Windows在当前目录(文件)打开cmd窗口
- 技术交流:老刘说NLP技术公众号开通
- python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog)
- 数据结构链表例程_如何掌握RxJava例程的四个结构
- Linux 进程号 端口号 互找
- html缩放排版乱了_交作业 | 代码排版逐行显现效果
- Layout自动布局(2)-手写代码
- JPG图片转换成Word文字教程分享
- 2021-02-14金蝶KIS旗舰版从采购订单下推外购入库单使用说明,金蝶盘点机PDA仓库条码管理
- ubuntu下安裝搜狗輸入法
- python上方菜单栏不见了如何恢复_word菜单栏不见了,如何恢复
- transition 属性
- mac原生壁纸,拿走不谢!
- 【实战记录分析】目录导航
- eax,ebx,ecx,edx,esi,edi,ebp,esp寄存器的作用
- Soft Labels for Ordinal Regression阅读笔记
- 阿里云短信 签名 模板编写
- Raspberry/Ubuntu 20.04命令行连接eap-gtc企业wifi
- HashSet里的元素是不能重复的,那用什么方法来区分重复与否呢?
热门文章
- 【Kawasaki川崎机器人码垛程序】CP180L-AC01
- 2022金三银四前端面试题预告
- Flask03_路由传参
- 我们应该怎样做需求分析?(一)需求调研
- inventor如何钣金出弧面_Inventor钣金设计教程
- 接口隔离原则(Interface Segregation Principle)
- C++位运算:与,或,非( , | , !)
- 人工智能的发展历程,AI ,路在何方(文章分享)
- IPaddr和IPaddr2的区别
- 求助,电脑关闭游戏后自动弹出dptf