C++ C++;实现向后推和向前弹出的自定义列表
我希望有人能帮助我。我正在努力为我正在制作的自定义列表正确地实现C++ C++;实现向后推和向前弹出的自定义列表,c++,list,C++,List,我希望有人能帮助我。我正在努力为我正在制作的自定义列表正确地实现push_back和pop_front方法。当我运行主程序时,它会冻结,windows会报告它停止工作。此列表用于生成队列。我已经创建了我的队列类,并使用stl列表对其进行了测试(对于我的作业,我还需要创建一个自定义列表),因此我相当确定问题出在我的列表中。我想我没有正确地编码push_back和pop_front。抱歉,如果这是一个愚蠢的问题,我试图搜索类似的案例,但找不到任何。我将感谢任何帮助 我的节点类 template<
push_back
和pop_front
方法。当我运行主程序时,它会冻结,windows会报告它停止工作。此列表用于生成队列。我已经创建了我的队列类,并使用stl列表对其进行了测试(对于我的作业,我还需要创建一个自定义列表),因此我相当确定问题出在我的列表中。我想我没有正确地编码push_back和pop_front。抱歉,如果这是一个愚蠢的问题,我试图搜索类似的案例,但找不到任何。我将感谢任何帮助
我的节点类
template<typename T>
class cNode{
public:
T nodeVal;
cNode<T> *next;
cNode<T> *prev;
cNode<T>();
cNode<T>(const T& v, cNode<T> *n, cNode<T> *p);
};
//Methods
//defualt constructor
template<typename T>
cNode<T>::cNode(){
};
//constructor with value value next and prev
template<typename T>
cNode<T>::cNode(const T& v, cNode<T> *n=NULL, cNode<T> *p=NULL){
nodeVal=v;
next=n;
prev=p;
};
模板
类cNode{
公众:
T nodeVal;
cNode*下一步;
中海油*prev;
cNode();
cNode(施工测试与验证、cNode*n、cNode*p);
};
//方法
//撤销构造函数
模板
cNode::cNode(){
};
//值为next和prev的构造函数
模板
cNode::cNode(常数T&v,cNode*n=NULL,cNode*p=NULL){
nodeVal=v;
next=n;
prev=p;
};
在我的列表中,我注释掉了其他方法,因为它们没有使用的是队列类
#include "cNode.h"
using namespace std;
template <typename T>
class cList{
private:
cNode<T> *frontNode;
cNode<T> *backNode;
int sizeOfList;
public:
cList();
bool empty();
// void push_front(const T& val);
void push_back(const T& val);
void pop_front();
// void pop_back();
T front();
// T back();
int size();
};
//Methods
//Constructor
template <typename T>
cList<T>::cList(){
frontNode = NULL;
backNode = NULL;
};
//Returns true if empty
template<typename T>
bool cList<T>:: empty(){
return frontNode == NULL;
};
//Adds to the back of the list
template<typename T>
void cList<T>:: push_back(const T& val){
cNode<T> *newNode;
newNode = new cNode<T>;
newNode->nodeVal=val;
//inserting in place
newNode->prev = backNode->prev;
newNode->next = backNode;
backNode->prev->next = newNode;
backNode->prev = newNode;
//update size
sizeOfList++;
};
//Removes from the front of the list
template<typename T>
void cList<T>:: pop_front(){
cNode<T> *df;
df = new cNode<T>;
df = frontNode;
df->next->prev=df->prev;
frontNode=frontNode->next;
delete df;
//update size
sizeOfList--;
};
//Returns value of of the front
template<typename T>
T cList<T>:: front(){
return frontNode->nodeVal;
};
//Returns the size of the list
template<typename T>
int cList<T>:: size(){
return sizeOfList;
};
#包括“cNode.h”
使用名称空间std;
模板
类cList{
私人:
cNode*前端节点;
cNode*反向节点;
int sizeOfList;
公众:
cList();
bool empty();
//无效推力前(常数T&val);
无效推回(常数T&val);
void pop_front();
//void pop_back();
T前面();
//T back();
int size();
};
//方法
//建造师
模板
cList::cList(){
frontNode=NULL;
backNode=NULL;
};
//如果为空,则返回true
模板
boolclist::empty(){
返回frontNode==NULL;
};
//添加到列表的后面
模板
无效客户端::推回(常量T&val){
cNode*新节点;
newNode=newcnode;
newNode->nodeVal=val;
//插入到位
newNode->prev=backNode->prev;
newNode->next=backNode;
backNode->prev->next=newNode;
backNode->prev=newNode;
//更新大小
sizeOfList++;
};
//从列表的前面删除
模板
void cList::pop_front(){
cNode*df;
df=新的cNode;
df=前节点;
df->next->prev=df->prev;
frontNode=frontNode->next;
删除df;
//更新大小
sizeOfList--;
};
//返回前面的值
模板
T cList::front(){
返回frontNode->nodeVal;
};
//返回列表的大小
模板
int cList::size(){
返回sizeOfList;
};
查看代码后立即发现的内容,
使用空值初始化backNode
和frontNode
,
但之后在推回
中,您为他们使用操作符->
,
在使用之前,您需要为它们分配内存
对算法进行少量修改以使其正常工作:
#include <cassert>
#include <cstdlib>
template <typename T> struct cNode {
T nodeVal;
cNode<T> *next;
cNode<T> *prev;
cNode<T>(const T &v = T(), cNode<T> *n = NULL, cNode<T> *p = NULL)
: nodeVal(v), next(n), prev(p) {}
};
template <typename T> class cList {
private:
cNode<T> head_;
size_t sizeOfList_;
typedef cNode<T> NT;
public:
cList() : sizeOfList_(0) {
head_.next = &head_;
head_.prev = &head_;
}
~cList() {
for (NT *p = begin(); p != end();) {
NT *next = p->next;
delete p;
p = next;
}
}
cNode<T> *cbegin() const { return head_.next; }
cNode<T> *begin() { return head_.next; }
cNode<T> *end() { return &head_; }
bool empty() const { return head_.next == &head_; }
void push_back(const T &val) {
NT *newNode = new NT(val);
NT *prev_end = end()->prev;
prev_end->next = newNode;
newNode->prev = prev_end;
newNode->next = end();
end()->prev = newNode;
++sizeOfList_;
}
void pop_front() {
if (empty())
return;
NT *next_in_list = begin()->next;
NT *prev_in_list = begin()->prev;
delete begin();
head_.next = next_in_list;
if (prev_in_list == end())
end()->prev = end();
--sizeOfList_;
}
T front() const {
assert(!empty());
return cbegin()->nodeVal;
}
size_t size() const { return sizeOfList_; }
};
int main() {
cList<int> l;
assert(l.size() == 0);
assert(l.empty());
l.push_back(10);
assert(!l.empty());
assert(l.size() == 1);
assert(l.front() == 10);
l.pop_front();
assert(l.size() == 0);
assert(l.empty());
for (int i = 5; i < 17; ++i)
l.push_back(i);
assert(l.size() == (17 - 5));
assert(l.front() == 5);
assert(!l.empty());
{
cNode<int> *p;
int i;
for (p = l.begin(), i = 5; p != l.end(); p = p->next, ++i) {
assert(p->nodeVal == i);
}
assert(i == 17);
}
l.pop_front();
assert(l.size() == (17 - 5 - 1));
assert(l.front() == 6);
assert(!l.empty());
l.pop_front();
assert(l.size() == (17 - 5 - 2));
assert(l.front() == 7);
assert(!l.empty());
}
#包括
#包括
模板结构cNode{
T nodeVal;
cNode*下一步;
中海油*prev;
cNode(常数T&v=T(),cNode*n=NULL,cNode*p=NULL)
:nodeVal(v)、next(n)、prev(p){}
};
模板类cList{
私人:
cNode负责人;
尺寸;
类型定义cNode NT;
公众:
cList():sizeOfList\u0{
head\uux.next=&head\ux;
head_uu.prev=&head_uu;
}
~cList(){
对于(NT*p=begin();p!=end();){
NT*next=p->next;
删除p;
p=下一个;
}
}
cNode*cbegin()常量{返回头\下一步;}
cNode*begin(){返回头\下一步;}
cNode*end(){return&head}
bool empty()常量{return head\uu0.next==&head\u0;}
无效推回(常数T&val){
NT*newNode=newnt(val);
NT*prev_end=end()->prev;
上一步->下一步=新节点;
newNode->prev=prev\u end;
newNode->next=end();
end()->prev=newNode;
++sizeOfList;
}
void pop_front(){
if(空())
返回;
NT*next\u在\u列表中=开始()->next;
NT*prev\u in_list=begin()->prev;
删除begin();
head_uu.next=_列表中的下一个_;
如果(列表中的上一个=结束())
end()->prev=end();
--sizeOfList;
}
T前()常数{
断言(!empty());
返回cbegin()->nodeVal;
}
size_t size()常量{return sizeOfList_;}
};
int main(){
克莱斯特l;
断言(l.size()==0);
断言(l.empty());
l、 推回(10);
断言(!l.empty());
断言(l.size()==1);
断言(l.front()==10);
l、 pop_front();
断言(l.size()==0);
断言(l.empty());
对于(int i=5;i<17;++i)
l、 推回(i);
断言(l.size()==(17-5));
断言(l.front()==5);
断言(!l.empty());
{
中海油*p;
int i;
对于(p=l.begin(),i=5;p!=l.end();p=p->next,+i){
断言(p->nodeVal==i);
}
断言(i==17);
}
l、 pop_front();
断言(l.size()==(17-5-1));
断言(l.front()==6);
断言(!l.empty());
l、 pop_front();
断言(l.size()==(17-5-2));
断言(l.front()==7);
断言(!l.empty());
}
您会发现这里的图表非常有用-绘制指针是绝对确定引用内容的一种方法
也就是说,这里有一些跳出的东西:
- 在构造函数中将
和frontNode
初始化为backNode
。当您在第一次NULL
推回操作中尝试取消引用这些
s时,会发生什么情况NULL
- 相关:执行一次
推回操作后,
将具有什么值?它应该有什么价值frontNode
- 如果您试图从空列表中弹出一个项目,会发生什么情况
- 在列表的每一端,结束节点应该有一个
和prev
为next
或另一个表示它们不指向任何地方的值NULL
NULL
s被取消引用,并且您没有更新所有需要更新的内容。解决这个问题的方法是画一张图表