链表的按条件删除
来源:互联网 发布:甘肃广播电视网络官网 编辑:程序博客网 时间:2024/06/11 18:48
一、链表整体代码概述
- 链表的建立和各种操作建立在单个删除和单个添加的函数之上,一般来说只要写好了这两个基本的函数,其他的函数只要判断好添加和删除的条件再调用这两个基本的函数就好了。
- 除此之外,链表的内存问题依旧要注意…注意好释放的顺序就可以了。
- 链表、二叉树等,需要考虑的特殊情况基本都是根节点为NULL的情况、以及到链表末尾的情况,在单个删除和单个添加函数中另外建立pop_front,pop_back,push_front,push_back几个特殊情况的函数也是一个好办法的。
二、头文件概述
- 这个代码的是双向链表的。不过除了多一个prev指针的简单处理,和单向链表完全没有区别。
- 这里只收录node的声明和list类的private声明。
class list { public: typedef int data_type; struct node { public: data_type data; node* next; node* prev; node(data_type data = 0, node* next = NULL, node* prev = NULL) : data(data), next(next), prev(prev){}; }; typedef node listNode; typedef node* listPointer; typedef unsigned int size_type; private: listPointer head; listPointer tail; size_type _size; };
三、按条件删除代码
- 首先是按照条件删除某些节点的代码。
list& list::remove_if(bool (*condition)(listPointer)){ int i,pos=0; //pos代表从0位开始一个个检查是否符合条件condition listPointer tmp=head; while(tmp!=NULL){ if(condition(tmp)){ tmp=tmp->next; erase(pos);//注意这时候pos不用++!因为删除了本位置的, }else{ //后面的就顶替了这个位置 tmp=tmp->next; pos++; //检查不符合条件,pos跳到下一位 } } return *this;}
- 这里有意思的地方就在pos在什么时候要++,就像你在跑步比赛中超过了第二名,那你现在是第几名一样的问题。
在删除了目前位置的节点之后,后面的节点的位置就变成了目前的pos,再判断时就不用再++了;同理,如果这个位置不符合condition,那pos自然要++移到下一位。
接下来是erase的代码。
void list::erase(int position){ int i; if(_size==0){ head=NULL; tail=NULL; return; } if(position>_size-1 || position<0) return; if(position==0){ pop_front(); return; } if(position==_size-1){ pop_back(); return; } listPointer tmp=head; listPointer tmp1=tmp->next; for(i=0;i<position-1;i++){ tmp=tmp->next; tmp1=tmp1->next; } tmp1->next->prev=tmp; tmp->next=tmp1->next; delete tmp1; _size--;}
- 作为基本的操作的函数,可以把它分为两部分:判断条件,处理特殊情况(一般是对链表首尾的操作);一般情况的操作。由于这里是双向链表,所以多了设定prev指针的操作,其他和单向链表的想法并无二致。
- 之后的pop代码,再处理根节点的特殊情况。除了只有一个节点的时候设定这个节点同时为首尾之外,似乎没有什么需要注意的地方。
void list::pop_front(void){ if(empty()) return; if(_size==1){ delete head; head=NULL; tail=NULL; _size--; return; } listPointer tmp=head; head=head->next; head->prev=NULL; delete tmp; _size--; if(_size==1){ tail=head; }}void list::pop_back(void){ if(empty()) return; if(_size==1){ delete head; head=NULL; tail=NULL; _size--; return; } listPointer tmp=tail; tail=tail->prev; tail->next=NULL; delete tmp; _size--; if(_size==1){ head=tail; }}
四、小总结
- 真头疼啊这次双向链表,检讨自己这次作业的几个错误:
- 1、因为没有注意到几个函数可以复用(我把他们认为是所谓基本函数),所以多写了很多重复的步骤,导致bug产生的几率也变大了。
- 2、就如同按条件删除中讲的,“超过第二名”这样的问题没有想清楚,所以整个链出现了:删除的size没有问题,但是删除错节点的问题。
- 3、在测试较大的数据的时候出现了输入流溢出的情况…困惑了许久。
- 待续。
0 0
- 链表的按条件删除
- 链表满足条件的一次性多个删除
- 删除表中满足条件的记录
- 递归删除成功的条件
- 删除两个表的符合条件的数据
- Qt学习之按条件删除tableview的某一行
- 用游标删除所有符合条件的表
- LINQ批量删除符合条件的数据
- 删除 符合条件的多行
- LINQ批量删除符合条件的数据
- 删除 Map 中不满足条件的元素
- linux删除符合条件的文件
- linux删除满足条件的文件
- 删除list中符合条件的内容
- std::map 删除指定条件的元素
- C++ Vector 删除符合条件的元素
- 根据特定的条件删除文件
- myBatis中删除条件的拼接问题
- 11 个 Android Studio 的好用插件
- C++抽象编程——STL(5)——剔除重复元素
- linux的基本语法及一些设置
- 表格中的iframe实现打开多个网页
- 爬虫实战--抓取糗事百科前10页数据
- 链表的按条件删除
- JSON数据解析
- java中import导入自定义包
- SQLite Expert Professional 3查看SQLite数据
- tensorflow分类预测引发的性能测试
- 如何在angularjs里面选择一个按钮而不改变其他按钮的颜色
- 设计模式
- web网站无埋点技术,分析数据。
- 集合框架二