list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构

list源码2(参考STL源码--侯捷):constructor、push_back、insert

list源码3(参考STL源码--侯捷):push_front、push_back、erase、pop_front、pop_back、clear、remove、unique

list源码4(参考STL源码--侯捷):transfer、splice、merge、reverse、sort

transfer

list内部提供一个所谓的迁移技术:transfer,将某连续范围的元素迁移到某个指定的位置之前:

//将[first,last]内所有元素移动到position之前
void transfer(iterator position,iterator first,iterator last){
if(position!=last){
(*(link_type((*last.node).prev))).next=position.node; //
(*(link_type((*first.node).prev))).next=last.node; //
(*(link_type((*position.node).prev))).next=first.node; //
link_type temp=link_type((*position.node).prev); //
(*position.node).prev=(*last.node).prev; //
(*last.node).prev=(*first.node).prev; //
(*first.node).prev=temp; //
}
}

transfer所接受的[first,last]区间,可以存在同一个list里面,上述transfer并非公开接口,list的公开接口是splice;splice:将某个连续范围的元素从一个list移到另一个list的某个定点,使用如下:

#include<bits/stdc++.h>
using namespace std; int main() {
list<int> l1={,,,,,};
int a[]={,,,};
list<int> l2={a,a+}; list<int>::iterator it=find(l1.begin(),l1.end(),);
list<int>::iterator first=l2.begin();
list<int>::iterator last=l2.end();
if(*it==){
// l1.splice(it,l2);
l1.splice(it,l2,first,last);
} for(auto i:l1) cout<<i<<' ';//0 1 2 11 12 13 14 3 4 5
cout<<endl; l1.reverse();
for(auto i:l1) cout<<i<<' ';//5 4 3 14 13 12 11 2 1 0
cout<<endl; l1.sort();
for(auto i:l1) cout<<i<<' ';//0 1 2 3 4 5 11 12 13 14
cout<<endl;
return ;
}

splice

public:
//将x接合于position之前
void splice(iterator position,list& x){
if(!x.empty()){
transfer(position,x.begin(),x.end());
}
}
//将i所指元素接合于position所指位置之前,position和i可指向同一list
void splice(iterator position, list&, iterator i){
iterator j=i;
++j;
if(position==i||position==j) return;
transfer(position,i,j);
}
//将[first,last]内的所有元素接合于position所指位置之前
//position和[first,last]可指向同一个list
//position不能位于[first,last]之内
void splice(iterator position, list&, iterator first,iterator last){
if(last!=first){
transfer(position,first,last);
}
}

merge

//merge()将x合并到*this身上,两个list的内容都必须经过递增排序
template<class T,class Alloc>
void list<T,Alloc>::merge(list<T,Alloc>& x){
iterator first1=begin();
iterator last1=end();
iterator first2=x.begin();
iterator last2=x.end(); //注意:前提是两个链表都经过递增排序
while(first1!=last1&&first2!=last2){
if(*first2<*first1){
iterator next=first2;
tranfer(first1,first2,++next);
first2=next;
}
else
++first1;
if(first2!=last2)
transfer(last1,first2,last2);
}
}

 reverse

//reverse()内容逆置
template<class T,class Alloc>
void list<T,Alloc>::reverse(){
//以下判断:如果空链表或者仅有一个元素,就不进行任何操作
//使用size()==0||size()==1来判断,虽然也可以,但是比较慢
if(node->next==node||link_type(node->next)->next==node)
return;
iterator first=begin();
++first;
while(first!=end()){
iterator old=first;
++first;
transfer(begin(),old,first);
}
}

sort

//list不能使用STL算法sort(),必须使用自己的成员函数sort()
//本函数采用quicksort(看代码好像不是快排,而是归并
template<class T,class Alloc>
void list<T,Alloc>::sort(){
//以下判断:如果空链表或者仅有一个元素,就不进行任何操作
//使用size()==0||size()==1来判断,虽然也可以,但是比较慢
if(node->next==node||link_type(node->next)->next==node)
return;
//新的list作为辅助数据存放区
list<T,Alloc> carry;
list<T,Alloc> counter[];
int fill=;
while(!empty()){
carray.splice(carry.begin(),*this,begin());
int i=;
while(i<fill&&!counter[i].empty()){
counter[i].merge(carray);
carray.swap(counter[i++]);
}
carray.swap(counter[i]);
if(i==fill)
++fill;
}
for(int i=;i<fill;++i){
counter[i].merge(counter[i-]);
}
swap(counter[fill-]);
}

下面来解释一下sort的实现,以21,45,1,30,52,3,58,47,22,59,0,58为例:

1、counter[0]:21      注:counter[i]存放2i+1个数,当达到第2i+1个数时,移动数据到counter[i+1]中

2、counter[0]:21,45  注:counter[0]元素已满

counter0]:NULL

counter[1]:21,45

3、counter[0]:1

   counter[1]:21,45

4、counter[0]:1,30  注:counter[0]元素已满,利用merge合并counter[0]至counter[1]

   counter[1]:21,45

counter[0]:NULL

counter[1]:1,30,21,45  注:counter[1]元素已满,

counter[0]:NULL

counter[1]:NULL

counter[2]:1,30,21,45

......

最后得到:

   counter[0]:58

counter[1]:0,59

counter[2]:NULL

   counter[3]:1,3,21,30,47,45,52,58

再次归并得到最后结果。

参考地址:https://blog.csdn.net/shoulinjun/article/details/19501811

list源码4(参考STL源码--侯捷):transfer、splice、merge、reverse、sort的更多相关文章

  1. list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构

    list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...

  2. list源码2(参考STL源码--侯捷):constructor、push_back、insert

    list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...

  3. list源码3(参考STL源码--侯捷):push_front、push_back、erase、pop_front、pop_back、clear、remove、unique

    list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...

  4. vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷):空间分配.push_back vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 v ...

  5. vector源码2(参考STL源码--侯捷):空间分配、push_back

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...

  6. vector源码1(参考STL源码--侯捷):源码

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...

  7. vector源码(参考STL源码--侯捷):空间分配导致迭代器失效

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...

  8. STL 源码分析 (SGI版本, 侯捷著)

    前言 源码之前,了无秘密 algorithm的重要性 效率的重要性 采用Cygnus C++ 2.91 for windows cygwin-b20.1-full2.exe 下载地址:http://d ...

  9. STL源码阅读-functor与adapter

    为什么要用仿函数 函数指针不灵活,难以与STL其他组件配合使用 Adapter 将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作 STL中 ...

随机推荐

  1. k8s初始化搭建方法

    http://www.cnblogs.com/cocowool/p/kubeadm_install_kubernetes.html https://www.kubernetes.org.cn/doc- ...

  2. SQLServer · 最佳实践 · 透明数据加密TDE在SQLServer的应用

    转:https://yq.aliyun.com/articles/42270 title: SQLServer · 最佳实践 · 透明数据加密TDE在SQLServer的应用 author: 石沫 背 ...

  3. adb安装apk

    1.    安装配置 1.1安装包 下载adb.zip,解压至本机 1.2环境配置 将adb安装路径加入path中 2.    安装apk 使用数据线将Android手机与电脑连接,打开手机usb调试 ...

  4. 2T以上磁盘格式化

    1.安装软件 对于 Debian/Ubuntu 用户, 使用 APT-GET 命令或者 APT 命令来安装 parted #apt-get install -y parted 对于 RHEL/Cent ...

  5. 【翻译】Flume 1.8.0 User Guide(用户指南) source

    翻译自官网flume1.8用户指南,原文地址:Flume 1.8.0 User Guide 篇幅限制,分为以下5篇: [翻译]Flume 1.8.0 User Guide(用户指南) [翻译]Flum ...

  6. mysql 的 alter table 操作性能小提示

    通常情况下,修改表的结构一般不会有太大问题,无非就是一个 alter table 操作,但是对于大表做 alter 操作是一个大问题,请小伙伴们慎重. mysql执行大部分修改表结构操作方法是创建一个 ...

  7. PHP与Excel 笔记

    一:   PHP将数据导出Excel表中(投机型) 二: PHPExcel: Github上可以下载此插件包,用法如下: 前端: //上传阅卷员Excel文件 $("#upload_memb ...

  8. 一个简单的TensorFlow可视化MNIST数据集识别程序

    下面是TensorFlow可视化MNIST数据集识别程序,可视化内容是,TensorFlow计算图,表(loss, 直方图, 标准差(stddev)) # -*- coding: utf-8 -*- ...

  9. webpack踩坑--webpack 2.x升级至4.x

    一.安装webpack-cli,webpack@4.26.1 1.npm install webpack-cli -D 2.npm install webpack@4.26.1 -D 二.踩坑 执行n ...

  10. drawable内存管理

    图片对象: drawable bitmap etc.图片对象在Android上该缓存吗?什么时候缓存?怎么缓存?缓存后使用时怎么取出?怎么销毁?什么时候销毁? bitmap对象(new出来的) :需要 ...