.size和.empty
坑爹的list容器size方法--为了splice居然把复杂度设计为O(N)?
能用empty的时候,不要用size
empty可以保证常量复杂度,但list的size不保证
链表长度必须要遍历全部的链表元素才能获得,而不是用一个变量来表示
list size调用distance,distance内部遍历链表
sgi设计list的思路何以如此与众不同呢(话说微软的STL实现就没有这个SIZE方法的效率问题)?
看看作者自己的解释:http://home.roadrunner.com/~hinnant/On_list_size.html
开篇点题,原来作者是为
splice(iterator position, list& x, iterator first, iterator last);
方法所取的折衷,为了它的实现而把size方法设计成了O(N)。
splice方法就是为了把链表A中的一些元素直接串联到链表B中,如果size()设计为O(1)复杂度,那么做splice时就需要遍历first和last间的长度(然后把链表A保存的链表长度减去first和last(待移动的元素)之间的长度)!于是作者考虑到size方法设计为O(N),就无需在splice方法执行时做遍历了!
看看splice的实现:
void splice(iterator __position, list&, iterator __first, iterator __last) {
if (__first != __last)
this->transfer(__position, __first, __last);
}
再看看transfer干了些什么:
void transfer(iterator __position, iterator __first, iterator __last) {
if (__position != __last) {
// Remove [first, last) from its old position.
__last._M_node->_M_prev->_M_next = __position._M_node;
__first._M_node->_M_prev->_M_next = __last._M_node;
__position._M_node->_M_prev->_M_next = __first._M_node;
// Splice [first, last) into its new position.
_List_node_base* __tmp = __position._M_node->_M_prev;
__position._M_node->_M_prev = __last._M_node->_M_prev;
__last._M_node->_M_prev = __first._M_node->_M_prev;
__first._M_node->_M_prev = __tmp;
}
}
作者确实是考虑splice执行时,不用再做遍历,而是仅仅移动几个指针就可以了,因此牺牲了size的效率!
.size和.empty的更多相关文章
- 数据结构:队列queue 函数push() pop size empty front back
队列queue: push() pop() size() empty() front() back() push() 队列中由于是先进先出,push即在队尾插入一个元素,如:可以输出:Hello W ...
- Everything search syntax
Operators: space AND | OR ! NOT < > Grouping " " Search for an exact phrase. Wildcar ...
- C++_系列自学课程_第_5_课_vector容器_《C++ Primer 第四版》
再一次遇到 vector 这个单词; 每一次见到这个单词都感觉这个单词非常的 "高大上"; 数字遇到vector马上就可以360度旋转: 当 "电" 遇到vec ...
- java-集合3
浏览以下内容前,请点击并阅读 声明 Queue接口(队列) 需要对一些列的元素进行处理前,我们可以把他们放到Queue对象中,除了继承Collection接口的方法外,队列还有一些插入,删除和检查操作 ...
- Stack的c实现
用c语言实现stack的初始化,push,pop和Clear操作 #include<stdio.h> #include<stdlib.h> #include<assert ...
- stack栈
栈(statck)这种数据结构在计算机中是相当出名的.栈中的数据是先进后出的(First In Last Out, FILO).栈只有一个出口,允许新增元素(只能在栈顶上增加).移出元素(只能移出栈顶 ...
- sis9280触摸ic 基于rk3288 的安卓4.4的 多点触摸
前言:sis提供的驱动ic.基于rk3288的安卓系统.亲眼看到人家完成一次移植.很激动的记下一些东西..虽然我看不懂.其实现在的工作也不需要看懂.叫人协助就好,只需要知道有这个东西. 1linux下 ...
- d3-画雷达图-圆形弧线
本文转载 终极效果 源码 index.html <!DOCTYPE html> <html> <head> <meta http-equiv="Co ...
- Linux VFS Extended Attribute And Access Control Table
catalog . 简介 . 扩展属性 . 访问控制表 . 小结 0. 简介 许多文件系统都提供了一些特性,扩展了VFS层提供的标准功能,虚拟文件系统不可能为所有特性都提供具体的数据结构.超出标准的U ...
随机推荐
- VLOOKUP函数将一个excel表格的数据匹配到另一个表中
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...
- caffe rpn layer 中的 reshape layer
Reshape层:(改变blob的形状,N,C,W,H) layer { name: "reshape" type: "Reshape" bottom: &qu ...
- python---CMDB配置管理数据库
前戏:项目目的 是一个运维自动化管理项目: 为了减少人工干预,降低人员成本 ---资产管理 --操作管理 避免人员直接操作服务器,使用后台去统一操作 一:实现方式 (一)Agent基于shell命令实 ...
- ubuntu 使用小技巧
1. 查看网速 ethstatus ubuntu下用ethstatus可以监控实时的网卡带宽占用.这个软件能显示当前网卡的 RX 和 TX 速率,单位是Byte 安装 ethstatus 软件 sud ...
- Gulp安装笔记
前言 总的来说,玩gulp的流程是这样的: 安装nodejs -> 全局安装gulp -> 项目安装gulp以及gulp插件 -> 配置gulpfile.js -> 运行任务 ...
- Spring3.2 Contorller单元测试参数问题: java.lang.NoSuchMethodException
使用3.2做单元测试的时候发现这个问题,因为之前都是用3.0中的配置适配器使用AnnotationMethodHandlerAdapter,到3.2中升级为RequestMappingHandlerA ...
- 【清华集训 2017】小Y的地铁 [模拟退火]
小Y的地铁 Time Limit: 50 Sec Memory Limit: 256 MB Description Input Output 对于每组输入数据,输出一行一个整数,表示除掉这 n 个换 ...
- 基本控件文档-UIScrollView
CHENYILONG 基本控件文档-UIScrollView Fullscreen 基本使用作用UIScrollView可 ...
- 【leetcode 简单】 第一百四十六题 最长和谐子序列
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1. 现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度. 示例 1: 输入: [1,3,2,2,5,2,3,7] ...
- Linux基础-网络配置
任务目标:临时配置网络ip,网关,DNS,然后重启network:写配置文件永久保存网络配置 临时配置ens33网卡IP地址为192.168.30.99,查看更改完的ifconfig信息: 重新启动n ...