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,一经查实,立即删除!

相关文章

Node:解决Error: error:0308010C:digital envelope routines::unsupported的解决方法

问题描述 在使用vuepress搭建博客的时候&#xff0c;运行项目发现报错了&#xff0c;检查了node的版本是18&#xff0c;之前用的是16或14的版本&#xff0c;现在报&#xff1a;Error: error:0308010C:digital envelope routines::unsupported错误。 查找了一些资料&#xff0…

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

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

HOW - 保证 WebSocket 持续正常连接

一、基于 React 的 WebSocket 下面是一个React版本的WebSocket连接代码示例&#xff0c;展示了如何在React组件中实现WebSocket连接、心跳机制以及自动重连功能。 WebSocketManager.js 首先&#xff0c;我们可以创建一个 WebSocketManager 类来封装WebSocket的逻辑&#xff…

web前端 Vue 框架面试120题(六)

面试题 101 . 如何解决Vuex页面刷新数据丢失 &#xff1f; 参考回答&#xff1a; F5页面刷新&#xff0c;页面销毁之前的资源&#xff0c;重新请求&#xff0c;因此写在生命周期里的vuex数据是重新初始化&#xff0c;无法获取的&#xff0c;这也就是为什么会打印出空的原因。…

解决Oracle SQL语句性能问题——正确使用Hint(Hint概念、场景及具体语法)

10.5. 正确使用Hint 10.5.1. Hint概念及场景 调优SQL语句时,Oracle提供了很多可用的Hint。首先,你应该获取和分析SQL语句的执行计划,看能否通过改写SQL语句或其他方法来进行调整和优化,而不是直接使用Hint方法进行优化,最好在其他方法都确定无效或不合理之后再考虑使用H…

HTTPS 的加密过程 详解

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

概率论原理精解【4】

文章目录 度量空间概述理论基础定义特点高级概念广泛应用 性质例子应用 柯西数列柯西数列的定义柯西数列的例子 参考文献 度量空间 概述 设 f : R n → R m , f ˙ ( x ) 在 { x : ∣ x − x 0 ∣ < r } 内连续&#xff0c;则当 ∣ t ∣ < r 时&#xff0c; f:R^n\righ…

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;具备高可扩展性、高…

cephrgw元数据和数据布局

提示&#xff1a;每个rados object有如下几个组成部分&#xff0c;分别是omap&#xff08;omapheader、omapkey、omapval&#xff09;、xattr、data&#xff0c;相关的CLI command rados getomapheader {radosobjectname} -p {poolname} [--namespace{ns}] rados listomapkeys…

Eureka基本概念

Eureka基本概念 Eureka基本概念 一、服务消费者如何获取服务提供者的信息&#xff1f; 不管是消费服务者还是消费提供者&#xff0c;都是服务&#xff0c;服务启动之后会注册到eureka的注册中心去&#xff0c;当服务消费者请求调用某个服务的时候&#xff0c;会根据eureka注册…

【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计划未来将图像、视频和音频…

Vue 自定义组件编写 案例实战

index.vue <template><div><el-button type"primary" click"showDialog">添加邮递配置</el-button><el-dialog :title"dialogTitle" :visible.sync"dialogVisible" width"800px" :before-clos…

【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;本…