C++ STL : std::list,源码面前,了无秘密,大裤衩啥颜色材质给你写的明明白白,哈哈

eat std::list source code

list的好处是每次插入或删除一个元素,就配置或释放一个元素空间。因此,list对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的插入和元素移除都永远是常数时间。

可惜了当下有点忙能力欠缺,待有时间来补上可运行完整版本std::list源码实现

// DesignPatterns.cpp: 定义应用程序的入口点。
//#include "DesignPatterns.h"#include <list>
#include <utility>
#include <memory>
#include <set>
#include <malloc.h>
using namespace std;template<class T>
struct __list_node {typedef void* void_pointer;void_pointer prev; // 类型为 void*,其实可设为 __list_node<T>*void_pointer next;T data;
};template<class T, class Ref, class Ptr>
struct __list_iterator {typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, Ref, Ptr> self;typedef bidirectional_iterator_tag iterator_category;typedef T value_type;typedef Ptr pointer;typedef Ref reference;typedef __list_node<T>* link_type;typedef size_t size_type;typedef ptrdiff_t difference_type;link_type node;// constructor__list_iterator(link_type x) :node(x) {}__list_iterator() {}__list_iterator(const iterator& x) : node(x.node) {}bool operator==(const self& x) const { return node == x.node; }bool operator!=(const self& x) const { return node != x.node; }// 下面是对迭代器取值deference,取得是节点的数据值reference operator*() const { return (*node).data; }// 下面是迭代器的成员存取(member access)预算子的标准做法pointer operator->() const { return &(operator*()); }// 对迭代器累加1,就是前进一个节点self& operator++() {node = (link_type)((*node).next);return *this;}self operator++(int) {self tmp = *this;++*this;return tmp;}self& operator--() {node = (link_type)((*node).prev);return *this;}self operator--(int) {self tmp = *this;--*this;return tmp;}
};template<class T, class Alloc>
class list {
protected:// 中间加一层,就有了梦幻的数据typedef __list_node<T> list_node;public:// 组合一个数据的指针,链表不就有了么typedef list_node* link_type;protected:link_type node;// 专属之空间配置器,每次配置一个节点大小typedef simple_alloc<list_node, Alloc> list_node_allocator;protected:// 配置一个节点并传向link_type get_node() { return list_node_allocator::allocate(); }// 释放一个节点void put_node(link_type p) { list_node_allocator::deallocator(p); }// 产生(配置并构造)一个节点,带有元素值link_type create_node(const T& x) {link_type p = get_node();construct(&p->data, x); // 全局函数,构造/析构基本工具return p;}// 销毁(析构并释放)要给节点void destroy_node(link_type p) {destroy(&p->data);put_node(p);}
public:list() { empty_initialize(); }
protected:void empty_initialize() {node = get_node(); // 配置一个节点空间,令node指向它node->next = node; // 令node头尾都指向自己,不设元素值node->prev = node;}void push_back(const T& x) { insert(end(), x); }iterator insert(iterator position, const T& x) {link_type tmp = create_node(x); // 产生一个节点// 调整双向指针,使得tmp插进去tmp->next = position.node;tmp->prev = position.node->prev;(link_type(position.node->prev))->next = tmp;position.node->prev = tmp;return tmp;}void push_front(const T& x) { insert(begin(), x); }void push_back(const T& x) { insert(end(), x); }iterator erase(iterator position) {link_type next_node = link_type(position.node->next);link_type prev_node - link_type(position.node->prev);prev_node->next = next_node;next_node->prev = prev_node;destroy_node(position.node);return iterator(next_node);}void pop_front() {erase(begin());}void pop_back() {iterator tmp = end();erase(--tmp);}template<class T, class Alloc>void list<T, Alloc>::clear() {link_type cur = (link_type)node->next;while (cur != node) {link_type tmp - cur;cur = (link_type)cur->next;destroy_node(tmp);}node->next = node;node->prev = node;}template<class T, class Alloc>void list<T, Alloc>::remove(const T& value) {iterator first = begin();iterator last = end();while (first != last) {iterator next = first;++next;if (*first == value) erase(first);first = next;}}template<class T, class Alloc>void list<T, Alloc>::unique() {iterator first = begin();iterator last = end();if (first == last) return;iterator next = first;while (++next != last) {if (*first == *next) {erase(next);}else {first = next;}next = first;}}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 tmp = link_type((*position.node).prev);(*position.node.prev = (*last.node).prev;(*last.node).prev = (*first.node).prev;(*first.node).prev = tmp;}}
public:void splice(iterator position, list& x) {if (!x.empty_initialize())transfer(position, x.begin(), x.end());}void splice(iterator position, list&, iterator i) {iterator j = i;++j;if (position == i || position == j) return;transfer(position, i, j);}void splice(iterator position, list&, iterator first, iterator last) {if (first != last) {transfer(position, first, last);}}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;transfer(first1, first2, ++next);first2 = next;}else++first1;if (first2 != last2) transfer(last1, first2, last2);}}template<class T, class Alloc>void list<T, Alloc>::reverse() {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);}}template<class T, class Alloc>void list<T, Alloc>::sort() {if (node->next == node || link_type(node->next)->next == node)return;list<T, Alloc> carry;list<T, Alloc> counter(64);int fill = 0;while (!empty() {carry.splice(carry.begin(), *this, begin());int i = 0;while (i < fill && !counter[i].empty()) {counter[i].merge(carry);carry.swap(counter[i++]);}carry.swap(counter[i]);if (i == fill) ++fill;}for (int i = 1; i < fill; ++i){counter[i].merge(counter[i - 1]);}swap(counter[fill - 1]);}/** push_front,push_back,erase,pop_front,pop_back,clear* remove,unique,splice,merge,reverse,sort**/};int main()
{int i;std::list<int> ilist;std::cout << "size=" << ilist.size() << std::endl;ilist.push_back(0);ilist.push_back(2);ilist.push_back(3);ilist.push_back(4);std::cout << "size=" << ilist.size() << std::endl;std::list<int>::iterator ite;for (ite = ilist.begin(); ite != ilist.end(); ++ite) {std::cout << *ite << ' ';}std::cout << std::endl;ite = std::find(ilist.begin(), ilist.end(), 3);if (ite != ilist.end()) {ilist.insert(ite, 9);}std::cout << "size=" << ilist.size() << std::endl;std::cout << *ite << std::endl;for (ite = ilist.begin(); ite != ilist.end(); ++ite) {std::cout << *ite << ' ';}std::cout << std::endl;ite = std::find(ilist.begin(), ilist.end(), 2);if (ite != ilist.end()) {std::cout << *(ilist.erase(ite)) << std::endl;}for (ite = ilist.begin(); ite != ilist.end(); ++ite) {std::cout << *ite << ' ';}std::cout << std::endl;int iv[5] = { 5,6,7,8,9 };std::list<int> list2(iv, iv + 5);// 目前ilist的内容为 0 2 99 3 4ite = std::find(ilist.begin(), ilist.end(), 99);ilist.splice(ite, list2); // 0 2 5 6 7 8 9 99 3 4ilist.reverse(); // 4 3 99 9 8 7 6 5 2 0ilist.sort(); // 0 2 3 4 5 6 7 8 9 99return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言练习12周(15~16)

编写int fun(char s[])函数&#xff0c;返回字串中所有数字累加和 题干编写int fun(char s[])函数&#xff0c;返回字串中所有数字累加和。 若传入串"k2h3yy4x"返回整数9&#xff1b;若传入串"uud9a6f7*"返回整数22 //只填写要求的函数 int fun(cha…

JSON详细教程

&#x1f60a;JSON详细教程 &#x1f6a9;JSON简介☃️JSON语法规则&#x1f50a;JSON和JavaScript对象的区别 ☃️JSON数据类型字符串&#x1f50a;数字&#x1f50a;布尔值&#x1f50a;数组&#x1f50a;对象&#x1f50a;Null ☃️JSON对象&#x1f50a;访问JSON对象的值&a…

堆的应用(堆排序、Top-K问题)

文章目录 1 堆排序2 Top-K问题 1 堆排序 堆排序是一种基于二叉堆&#xff08;通常使用数组实现&#xff09;的排序算法。 它的基本思想是利用堆这种数据结构的性质&#xff0c;通过建立一个堆&#xff08;大堆或小堆&#xff09;&#xff0c;使得堆的根节点是所有节点中的最大值…

在线 SQL 模拟器SQL Fiddle使用简介

在线 SQL 模拟器SQL Fiddle使用简介 有时候&#xff0c;我们想去验证 SQL语句&#xff0c;却缺少数据库环境&#xff0c;那该怎么办呢&#xff1f; 这时候在线 SQL 模拟器就有了用武之地。SQL 模拟器免安装&#xff0c;可以在网页直接运行 SQL 。 SQL Fiddle 支持 MySQL、Orac…

C++ Qt QString用法详解与代码演示

作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 文章目录 创建和初始化长度和容量修改字符串字符串比较查找和提取数值转换arg格式化`arg` 的基本用法精确控制占位符多占位符的复杂替换使用大括号占位符注意事项迭代Unicode 和编码QSt…

SystemVerilog 入门

文章目录 包定义SystemVerilog 数据类型结构体 SystemVerilog 过程块可嵌套模块接口 System Verilog 的优点 提高了硬件建模能力、编码效率和抽象能力&#xff1b;RTL 级、系统级行为描述&#xff1b; 增强了验证能力和为大规模复杂设计编写有效、无竞争测试程序的断言功能&am…

spring-framework-5.2.25.RELEASE源码环境搭建

环境准备 spring-framework-5.2.25.RELEASEIntelliJ IDEA 2022.3.1java version “11.0.20” 2023-07-18 LTSGradle 5.6.4java version “1.8.0_301” 下载spring-framework-5.2.25.RELEASE源码 git clone https://gitee.com/QQ952051088/spring.git cd spring gradlew buil…

[学习记录]Node event loop 总结流程图

文章目录 文章来源根据内容输出的流程图待处理遗留的问题参考 文章来源 详解JavaScript中的Event Loop&#xff08;事件循环&#xff09;机制 根据内容输出的流程图 待处理 这里从polling阶段开始 好像有些问题 遗留的问题 为什么“在I/O事件的回调中&#xff0c;setImmediate…

mysql 存储过程do while

关于mysql 存储过程内实现循环&#xff0c;在用repeat 时发现&#xff0c; 很容易因为done的值循环终止。为此研究了下 do while来实现 循环。 过程和repeat 大差不差&#xff0c;值得注意的是 多了一个循环次数&#xff0c;通过该变量去定义我们要循环的次数。 做了一个简易…

Android 13.0 开机过滤部分通知声音(莫名其妙的通知声音)

1.概述 在13.0的系统定制开发产品的中,有时候在系统开机的时候会有一些通知的声音,但是由于系统模块太多,也搞不清楚到底是哪个模块发出的通知声音,所以就需要从通知的流程来屏蔽这些通知声音,接下来看具体怎么实现在开机的时候过滤开机声音的功能 2.开机过滤部分通知声音…

深度学习:全面了解深度学习-从理论到实践

深度学习&#xff1a;全面了解深度学习-从理论到实践 摘要&#xff1a;本文旨在为读者提供一份全面的深度学习指南&#xff0c;从基本概念到实际应用&#xff0c;从理论数学到实践技术&#xff0c;带领读者逐步深入了解这一领域。我们将一起探讨深度学习的历史、发展现状&#…

使用Tensorboard可视化 遇到无法访问此网站

问题&#xff1a; 使用Tensorboard可视化 遇到无法访问此网站 解决方法&#xff1a;后面加上服务器ip[参考] tensorboard --logdir目标目录 --hostxxx.xxx.xxx.xx

每天学一个电脑知识day1:盘符是什么?

在计算机中&#xff0c;盘符是用来标识和访问存储设备的一个符号或名称。 它常用于操作系统中&#xff0c;用于表示硬盘驱动器、光盘驱动器、USB驱动器等存储设备的逻辑标识符。 在Windows操作系统中&#xff0c;盘符通常以一个字母加上一个冒号来表示&#xff0c;如C:、D:等…

字符串读入方式(c/c++)

1.cin>> 不读取空格和换行 例如,写完cin>>n之后&#xff0c;可以写getchar(),防止后续读入的第一个字符串不是题目所给。 2.string 类型&#xff0c;getline(cin,s)&#xff0c;可以读带有空格的字符串 3.char 类型&#xff0c;scanf("%s[^\n]",s)…

leetcode LCR24反转单链表

反转单链表 题目描述 题目分析 先来说迭代的思想&#xff1a; 上面next cur->next应该放在cur->next pre前面执行&#xff0c;这里笔误 再来说递归的思想&#xff1a; 题目代码 这个代码里面我加了我自己写的测试数据&#xff0c;自己可以去找对应的部分&#xff0c…

VSCode 开发必备插件

Chinese&#xff08;Simplified&#xff09;(简体中文) VSCode 中文 Error Lens 代码基础报错提示&#xff0c; 必备 HTML CSS Support html 和 css 支持, 提示 Auto Close Tag 自动补全 html 标签 Auto Rename Tag 修改 html 标签&#xff0c;自动帮你完成尾部闭合标签…

【功能测试】软件系统测试报告

1.引言 1.1.目的 本测试报告为 xxx 系统测试报告&#xff0c;本报告目的在于总结测试阶段的测试及测试结果分析&#xff0c;描述系统是否达到需求的目的。 本报告预期参考人员包括测试人员、测试部门经理、开发人员、项目管理人员等。 1.2.参考文档 《xxxx系统需求规格说明…

Java线程安全问题

什么是线程安全问题 用程序模拟线程安全问题 主线程 package com.itheima.d3;public class ThreadTest {public static void main(String[] args) {//1、创建一个账户对象&#xff0c;代表两个人的共享账户Accout acc new Accout("ICBC-110",100000);//2、创建两个…

Django回顾【二】

目录 一、Web框架 二、WSGI协议 三、 Django框架 1、MVC与MTV模型 2、Django的下载与使用 补充 3、启动django项目 补充 5、 Django请求生命周期 四、路由控制 1、路由是什么&#xff1f; 2、如何使用 3、path详细使用 4、re_path详细使用 5、反向解析 6、路由…