Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;实现向后推和向前弹出的自定义列表_C++_List - Fatal编程技术网

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
    。当您在第一次
    推回操作中尝试取消引用这些
    NULL
    s时,会发生什么情况

  • 相关:执行一次
    推回操作后,
    frontNode
    将具有什么值?它应该有什么价值

  • 如果您试图从空列表中弹出一个项目,会发生什么情况

  • 在列表的每一端,结束节点应该有一个
    prev
    next
    NULL
    或另一个表示它们不指向任何地方的值

这里的要点是,您有很多
NULL
s被取消引用,并且您没有更新所有需要更新的内容。解决这个问题的方法是画一张图表