C++基础语法:STL之容器(5)--序列容器中的list(二)

前言
     

         "打牢基础,万事不愁" .C++的基础语法的学习

引入

        序列容器的学习.以<C++ Prime Plus> 6th Edition(以下称"本书")内容理解

        本书中容器内容不多只有几页.最好是有数据结构方面的知识积累,如果没有在学的同时补上

         接上一篇C++基础语法:STL之容器(4)--序列容器中的list(一)-CSDN博客

list(双向链表)  

         本书内容解读  

         第3部分除序列和可反转容器的函数外,list模板类还包含了链表专用的成员函数。表16.9列出了其中一些(有关STL方法和函数的完整列表,请参见附录G)。通常不必担心Alloc模板参数,因为它有默认值。

          ----看见了STL中的list,发现和自己写的不太一样,他有两个参数,表示为list<T,Alloc>,不过感觉问题也不是很大,代码主要说的是思路.

         照着成员函数的说明当成需求,前面是给出的函数原型,试着写一写算法.

        merge()合并算法看起来有点复杂,不写;remove前面有个相同名称的函数,因为想要调用之前的remove()函数,所以把他改为removeValue;splice()要用到迭代器,不写.把前面的容器类定义拿过来


template<class T>
class list{enum{MAX=10}int lsize;                        //list最大元素数量int items;                        //list内当前的元素个数class Node{                       //声明结点类public:                           //结点数据向外部类公开T t;Node *front;Node *next;Node(T val):t(val),front(0),next(0){}Node(){}                      //默认构造函数,为初始化时使用}Node* first;Node* last;
public:list(int num=MAX);                //构造函数   void add(Node* n,T& t);           //添加元素t到结点n后面T remove(Node* n);                //删除地址为n的结点//下面三个是将要实现的函数void removeValue(const T& val);   //删除val的所有实例void sort();                      //使用<运算符对链表进行排序Node* findNode(const T& t);       //排序中用到的函数void unique();                    //将连续的相同元素压缩成单个元素
}

         注意:下列代码为了练手,试图重现逻辑,不保证准确.  

        1>删除val的所有实例

        思路:遍历list,找到一个删一个.因为已定义了remove(Node* n),所以省事一些.

template<class T>
void list<T>::removeValue(const T& val){if(items==0){                                //空链表直接返回std::cout<<"链表内没有数据"<<std::endl;return;}list<T>::Node* p=first;                      //声明指针指向链表头结点bool flag=false;                             //声明标志位;     while(p){                                    //遍历链表if(p->t==val){remove(p);                           //调用删除结点函数flag=true;                           //标志位改变}p=p->next;                               //指针指向下一个结点}if(flag==true)std::cout<<"数据已全部删除"<<std::endl; elsestd::cout<<"链表内没有您想删除的数据"<<std::endl;  
}

          2>sort排序,从小到大排序,最小的放链表前面

           思路:要排序,我只知道冒泡排序,链表排序可以仿照冒泡排序算法吗?

            把链表"打散"成数组,然后给数组排序,接着把排好序后的结点重新找出来,依次挂到first后面.

             问题来了,现在的函数只能从结点访问到数据t,还没有从数据t访问到结点的函数,加一个呗    

template<class T>
Node* list<T>::findNode(const T& t){          //结点查找函数list<T>::Node * p=first;while(p){if(p->t==t)std::cout<<"您查找的数据已找到"<<std::endl;return p;p=p->next;                            //指向下一个结点}std::cout<<"您查找的数据不存在"<<std::endl;return nullptr;
}

         接下来按照冒泡排序的思路,把数据从小到大排列

template<class T>
void list<T>::sort(){                 //排序算法vector<T> a;List<T>::Node* p=first;while(p){a.push_back(p->t);            //元素取出来放进vector里p=p->next;                    //指针指向下一个结点}/*以下是冒泡排序*/for(int i=0;i<items-1;i++){for(int j=0;j<items-i-1;j++){if(a[j]>=a[j+1]){T tmp;tmp=a[j+1];a[j+1]=a[j];a[j]=tmp;}}}//到这里排序完成,从小到大,从a[0]到a[items-1]/*还原成结点,并依次挂到first后面*/Node* tmp=first;                   //声明临时结点tmp帮first整理,用上面的p也行for(int i=0;i<items;i++){
//两句说明结点后面是tmp->nextfindNode(a[i])->next=tmp->next;    tmp->next->front=findNode(a[i]);   
//两句说明结点前面是tmp;        tmp->next=findNode(a[i]); findNode(a[i])->front=tmp; 
//tmp结点指向新结点,为下次整理做准备;tmp=findNode(a[i]);        } last=tmp;                           //最后让last指向tmp;
}

        ----然而问题又来了,list并不检查两个相同的值,上面的findNode函数有bug该怎么办?想解决肯定是有办法的,比如给Node结点来个编号(题外话:黑皮书上有讲,那是本好书但是挺难)

    class Node{                       //声明结点类static int num;                   //静态变量,给对象编号用public:                           //结点数据向外部类公开int id;T t;Node *front;Node *next;Node(T val):t(val),front(0),next(0),id(num++){}Node():id(num++){}            //默认构造函数,为初始化时使用}

        但这样要耗费空间,查找结点代码也要改动,比较麻烦.所以我建议在排序之前先把多余的重复值去掉,也就是先调用下面要写的的unique()函数.

        ----除了这个问题还有个问题:让类型T的元素怎么比较?重载运算符吗?

/*???????????*/
bool operator<(T& t){    //起不了作用return *this < t
}

        如果从完全泛型的角度来讲,不可能成立.只能在调用时做出约束,如int,char,double等类型自带大小判断的才可以调用sort().

        如果对象中有部分元素是可以排序的,如有一个int属性,那么按照前面的思路,让其反向查找排序,这不是容器的事,应该在外面定义函数来解决.        

class Person{int age;        //这个可以排序string name;
}

        3>压缩链表,去掉多余元素

        思路:用一个集合a存储链表里的数据,遍历链表的同时,遍历集合a.当新元素在集合a里找到时,删除,当没有找到时,加入集合a.

template<class T>
void list<T>::unique(){              //将连续的相同元素压缩成单个元素list<T>::Node* p=first;vector<T> a;while(p){for(pt=a.begin();pt!=a.end();pt++){if(p->t==*pt){remove(p);           //调用删除结点函数}a.push_back(p->t);       //元素取出来放进vector里}p=p->next;                    //指针指向下一个结点}
}                  

        此外本书P699举了个例子,讲几种api的使用,看看即可.

链表梳理

        链表的定义和使用流程:数据→结点→链表.1.把数据放入结点;2.结点指针生成链表.

        链表是一个结点指针的集合,指针元素之间用结点指针相连接.头结点是链表的入口.

        链表的难点是区分指针变量和指针常量.

        链表里的元素是结点指针,他们是常量,要访问他们或者修改他们用的是指针变量.常见的指针变量有头结点,尾结点.他们时刻要保证逻辑正确,也是算法的保证. 

后记

        一天更了两篇,大热天还觉得挺兴奋.数据结构应该算是编程的分水岭,如果真的喜欢会享受代码和写作的过程.如果一时学不进去也挺难受,但也不要着急慢慢来,许多人也经历过那个过程.一起加油. 

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

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

相关文章

excel系列(三) - 利用 easyexcel 快速实现 excel 文件导入导出

一、介绍 在上篇文章中&#xff0c;我们介绍了 easypoi 工具实现 excel 文件的导入导出。 本篇我们继续深入介绍另一款更优秀的 excel 工具库&#xff1a;easyexcel 。 二、easyexcel easyexcel 是阿里巴巴开源的一款 excel 解析工具&#xff0c;底层逻辑也是基于 apache p…

HTTPS 的加密过程 详解

HTTP 由于是明文传输&#xff0c;所以安全上存在以下三个风险&#xff1a; 窃听风险&#xff0c;比如通信链路上可以获取通信内容。篡改风险&#xff0c;比如通信内容被篡改。冒充风险&#xff0c;比如冒充网站。 HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议&#xff0c…

Spring Cloud LoadBalanced

负载均衡(Load Balance&#xff0c;简称 LB) 是⾼并发, ⾼可⽤系统必不可少的关键组件. 当服务流量增⼤时, 通常会采⽤增加机器的⽅式进⾏扩容, 负载均衡就是⽤来在多个机器或者其他资源中, 按照⼀定的规则合理分配负载. 负载均衡的⼀些实现 就像是eureka中对请求进行轮询的…

Java对象创建过程的解析

Java对象创建过程的解析 1. 类的加载与连接2. 内存分配2.1 分配方式2.2 本地线程缓冲分配&#xff08;TLAB&#xff09; 3. 初始化内存4. 设置对象头 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 对象的创建是一个涉及多个步骤的复杂过程…

Qt:26.Qt项目:贪吃蛇游戏

一、项目功能演示&#xff1a; 开始界面可以点击进入游戏。 点击进入游戏之后&#xff0c;切换到选项界面&#xff0c;该界面可以选择游戏难度&#xff0c;回退&#xff0c;以及查询最近一次游戏得分。 游戏具体界面如下。贴图啥的可以自己换&#xff0c;本人审美不咋行&#x…

[SUCTF 2019]EasySQL1

这是一个简单的SQL注入题&#xff0c;但是因为我的SQL基础约等于0&#xff0c;所以做起来很难。 首先试试引号是否被过滤 可以看到单引号、双引号都被过滤了&#xff0c;试试其他的盲注都不行&#xff0c;基本上可以确定不能用这种方法。 在测试的过程中发现&#xff0c;输入…

RICHTEK立锜科技 WIFI 7电源参考设计

什么是WIFI 7? WiFi 7&#xff08;Wi-Fi 7&#xff09;是下一代Wi-Fi标准&#xff0c;对应的是IEEE 802.11将发布新的修订标准IEEE 802.11be –极高吞吐量EHT&#xff08;Extremely High Throughput &#xff09;。Wi-Fi 7是在Wi-Fi 6的基础上引入了320MHz带宽、4096-QAM、Mu…

oceanbase架构、功能模块、数据存储、特性、sql流转层等概念详解

一、架构图 OceanBase 数据库采用无共享&#xff08;Shared-Nothing&#xff09;分布式集群架构&#xff0c;各个节点之间完全对等&#xff0c;每个节点都有自己的 SQL 引擎、存储引擎、事务引擎&#xff0c;运行在普通 PC 服务器组成的集群之上&#xff0c;具备高可扩展性、高…

【LabVIEW作业篇 - 4】:属性节点赋值和直接节点赋值的区别体现

文章目录 属性节点赋值和直接节点赋值的区别体现 属性节点赋值和直接节点赋值的区别体现 创建5个圆形指示灯&#xff0c;然后循环点亮&#xff0c;先给圆形指示灯赋值假变量&#xff0c;然后再进行循环。 运行结果&#xff0c;观察结果&#xff0c;发现刚开始运行时&#xff0…

引领小模型潮流!OpenAI发布功能强大且成本低的GPT-4o mini

GPT-4o mini的成本比GPT-3.5 Turbo低了超过60%&#xff0c;其聊天表现优于Google的Gemini Flash和Anthropic的Claude Haiku。该模型从周四开始对ChatGPT的免费用户、ChatGPT Plus用户和团队订阅用户开放&#xff0c;并将在下周向企业用户开放。OpenAI计划未来将图像、视频和音频…

【Leetcode】一、排序

文章目录 1、选择排序2、冒泡排序3、插入排序 1、选择排序 给定数组arr&#xff0c;其长度为n。实现思路&#xff1a; 遍历数组&#xff0c;从0 ~ n - 1&#xff0c;找到最小的&#xff0c;找到后&#xff0c;和数组的第一个元素互换位置继续新一轮遍历&#xff0c;从1 ~ n -…

路网双线合并单线——ArcGIS 解决方法

路网双线合并成单线是一个在地图制作、交通规划以及GIS分析中常见的需求。双线路网定义&#xff1a;具有不同流向、不同平面结构的道路。此外&#xff0c;车道数较多的道路&#xff08;例如&#xff0c;双黄实线车道数大于4的道路&#xff09;也可以视为双线路网&#xff0c;本…

扩容升级丨极海正式推出G32A1465系列汽车通用MCU,驱动智驾再进阶

继2023年推出G32A系列汽车通用平台首发产品G32A1445系列后&#xff0c;极海宣布正式推出G32A1465系列全新汽车通用MCU&#xff0c;以满足日益增长的智能驾驶应用需求。作为升级迭代产品&#xff0c;G32A1465专为应用范围不断扩大的高运算要求而设计&#xff0c;集成丰富的通信接…

数据结构(5.2_3)——二叉树的存储结构

二叉树的顺序存储 #define MAXLEN 255struct TreeNode {ElemType value;//结点中的数据元素bool isEmpty;//结点是否为空 };void main() {TreeNode t[MaxSize]; } 定义一个长度为MaxSize的数组t&#xff0c;按照从上至下、从左至右的顺序依次存储完全二叉树中的各个结点 几个…

前端组件化探索与实践:Vue自定义暂无数据组件的开发与应用

摘要 随着前端开发技术的不断进步&#xff0c;组件化开发已成为提升开发效率、降低维护成本的关键手段。本文旨在通过介绍一款Vue自定义暂无数据组件的开发与实践&#xff0c;深入探讨前端组件化开发的重要性、优势及其在实际项目中的应用。 一、引言 在前端开发中&#xff0…

七天打造一套量化交易系统-Day0-量化投资发展历程

七天打造一套量化交易系统-Day0-量化投资发展历程 1、本间宗久&#xff08;1724-1803&#xff09;2、朱尔斯雷格纳特 Jules Regnault&#xff08;1834—1894&#xff09;3、拉尔夫纳尔逊艾略特&#xff08;1871-1948&#xff09;4、爱德华索普(Edward O. Thorp)&#xff08;193…

windows中使用Jenkins打包,部署vue项目完整操作流程

文章目录 1. 下载和安装2. 使用1. 准备一个 新创建 或者 已有的 Vue项目2. git仓库3. 添加Jenkinsfile文件4. 成功示例 1. 下载和安装 网上有许多安装教程,简单罗列几个 Windows系统下Jenkins安装、配置和使用windows安装jenkins 2. 使用 在Jenkins已经安装的基础上,可以开始下…

Element UI DatePicker选择日期范围区间默认显示前一个月和本月

要求&#xff1a;点击el-date-picker选择时间范围时&#xff0c;默认展开当月和上个月。 但是Element UI的组件默认展开的是本月和下一个月&#xff0c;如下图所示&#xff1a; 改为 <span click"changeInitCalendarRange"><el-date-picker v-model"r…

IT产品研发全生命周期【详细说明】

阶段步骤任务负责人产品管理用户故事收集和理解用户需求&#xff0c;创建用户故事产品经理需求分类分类用户故事&#xff0c;组织和优先级排序需求经理可行性分析评估需求的技术可行性与实现难度研发经理需求转换将需求转化为具体的产品特性或功能要求需求经理需求管理创建需求…

Android 视频亮度图标

attrs.xml <?xml version"1.0" encoding"utf-8"?> <resources><!--图标颜色--><attr name"ijkSolid" format"color|reference" /><!--圆角大小--><attr name"ijkRadius" format"d…