C++中的遍历队列

问题描述:

我有一个需要打印的C++队列。打印第一个节点然后删除它很容易,然后重新打印第一个节点,然后再将其作为第二个节点。但是,这将删除整个列表只是为了打印一次......作为一项解决方案,我创建了一个临时队列对象,将其传递给我的打印方法,并执行与第一个对象相同的操作,除非它使用使队列变为动态的指针,因此从第一个复制的对象中删除它们仍然会删除相同的数据。我对指针不太熟悉,但我确定必须有一个简单的方法来做到这一点,有什么建议吗?C++中的遍历队列

下面的代码:

queue2 = queue1; // Temporary queue is assigned values of main queue 
queue2.printQueue(); // Temporary queue is passed to print method 

这里是我的打印方法:

int numberPrinted = 0; 
while (!isEmptyQueue()) 
{ 
cout << numberPrinted + 1 << ": " << front() << "\n"; 
deleteQueue();  
numberPrinted++; 
} 

队列类文件:

#ifndef H_linkedQueue 
#define H_linkedQueue 

#include <iostream> 
#include <cassert> 
#include "queueADT.h" 

using namespace std; 

//Definition of the node 
template <class Type> 
struct nodeType 
{ 
    Type info; 
    nodeType<Type> *link; 
}; 


template <class Type> 
class linkedQueueType: public queueADT<Type> 
{ 
public: 
    bool operator== 
        (const linkedQueueType<Type>& otherQueue); 

    bool isEmptyQueue() const; 
     //Function to determine whether the queue is empty. 
     //Postcondition: Returns true if the queue is empty, 
     //    otherwise returns false. 

    bool isFullQueue() const; 
     //Function to determine whether the queue is full. 
     //Postcondition: Returns true if the queue is full, 
     //    otherwise returns false. 

    void initializeQueue(); 
     //Function to initialize the queue to an empty state. 
     //Postcondition: queueFront = NULL; queueRear = NULL 

    Type front() const; 
     //Function to return the first element of the queue. 
     //Precondition: The queue exists and is not empty. 
     //Postcondition: If the queue is empty, the program 
     //    terminates; otherwise, the first 
     //    element of the queue is returned. 

    Type back() const; 
     //Function to return the last element of the queue. 
     //Precondition: The queue exists and is not empty. 
     //Postcondition: If the queue is empty, the program 
     //    terminates; otherwise, the last 
     //    element of the queue is returned. 

    void addQueue(const Type& queueElement); 
     //Function to add queueElement to the queue. 
     //Precondition: The queue exists and is not full. 
     //Postcondition: The queue is changed and queueElement 
     //    is added to the queue. 

    void deleteQueue(); 
     //Function to remove the first element of the queue. 
     //Precondition: The queue exists and is not empty. 
     //Postcondition: The queue is changed and the first 
     //    element is removed from the queue. 
    int numberOfNodes(); 
    // Return number of nodes in the queue. 
    void printQueue(); 
    //Print the queue. 

    linkedQueueType(); 
     //Default constructor 

    linkedQueueType(const linkedQueueType<Type>& otherQueue); 
     //Copy constructor 

    ~linkedQueueType(); 
     //Destructor 

private: 
    nodeType<Type> *queueFront; //pointer to the front of 
           //the queue 
    nodeType<Type> *queueRear; //pointer to the rear of 
           //the queue 
    int count; 
}; 

    //Default constructor 
template<class Type> 
linkedQueueType<Type>::linkedQueueType() 
{ 
    queueFront = NULL; //set front to null 
    queueRear = NULL; //set rear to null 
} //end default constructor 

template<class Type> 
bool linkedQueueType<Type>::isEmptyQueue() const 
{ 
    return(queueFront == NULL); 
} //end 

template<class Type> 
bool linkedQueueType<Type>::isFullQueue() const 
{ 
    return false; 
} //end isFullQueue 

template <class Type> 
void linkedQueueType<Type>::initializeQueue() 
{ 
    nodeType<Type> *temp; 

    while (queueFront!= NULL) //while there are elements left 
           //in the queue 
    { 
     temp = queueFront; //set temp to point to the 
          //current node 
     queueFront = queueFront->link; //advance first to 
             //the next node 
     delete temp; //deallocate memory occupied by temp 
    } 

    queueRear = NULL; //set rear to NULL 
} //end initializeQueue 


template <class Type> 
void linkedQueueType<Type>::addQueue(const Type& newElement) 
{ 
    nodeType<Type> *newNode; 

    newNode = new nodeType<Type>; //create the node 

    newNode->info = newElement; //store the info 
    newNode->link = NULL; //initialize the link field to NULL 

    if (queueFront == NULL) //if initially the queue is empty 
    { 
     queueFront = newNode; 
     queueRear = newNode; 
    } 
    else  //add newNode at the end 
    { 
     queueRear->link = newNode; 
     queueRear = queueRear->link; 
    } 
    count++; 
}//end addQueue 

template <class Type> 
Type linkedQueueType<Type>::front() const 
{ 
    assert(queueFront != NULL); 
    return queueFront->info; 
} //end front 

template <class Type> 
Type linkedQueueType<Type>::back() const 
{ 
    assert(queueRear!= NULL); 
    return queueRear->info; 
} //end back 

template <class Type> 
void linkedQueueType<Type>::deleteQueue() 
{ 
    nodeType<Type> *temp; 

    if (!isEmptyQueue()) 
    { 
     temp = queueFront; //make temp point to the 
          //first node 
     queueFront = queueFront->link; //advance queueFront 

     delete temp; //delete the first node 

     if (queueFront == NULL) //if after deletion the 
           //queue is empty 
      queueRear = NULL; //set queueRear to NULL 
     count--; 
    } 
    else 
     cout << "Cannot remove from an empty queue" << endl; 
}//end deleteQueue 


    //Destructor 
template <class Type> 
linkedQueueType<Type>::~linkedQueueType() 
{ 
    //Write the definition of the destructor 
} //end destructor 

template <class Type> 
bool linkedQueueType<Type>::operator== 
        (const linkedQueueType<Type>& otherQueue) 
{ 
    bool same = false; 

    if (count == otherQueue.count) 
     same = true; 

    return same; 

} //end assignment operator 

    //copy constructor 
template <class Type> 
linkedQueueType<Type>::linkedQueueType 
       (const linkedQueueType<Type>& otherQueue) 
{ 
    //Write the definition of the copy constructor 
}//end copy constructor 
template <class Type> 
int linkedQueueType<Type>::numberOfNodes() 
{ 
    return count; 

} 

template <class Type> 
void linkedQueueType<Type>::printQueue() 
{ 
    int numberPrinted = 0; 
while (!isEmptyQueue()) 
{ 
cout << numberPrinted + 1 << ": " << front() << "\n"; 
deleteQueue();  
numberPrinted++; 
} 
} 
#endif 
+1

您正在使用某种标准队列类的队列类,还是您自己写的东西?无论哪种方式,它是否提供任何种类的迭代器? – 2013-03-27 23:59:56

+0

这是一个标准的队列类,我修改了一下。我不这么认为。我会发布课程文件... – Blake 2013-03-28 00:00:59

您的队列的printQueue方法已经访问了队列的民营内部。而不是使用公共接口来打印队列,只需使用内部queueFront指针并遍历列表,打印每个元素。

喜欢的东西(因为这功课伪代码):

for(node* n = queueFront; n; n = n->next) 
{ 
    // Print data from node n. 
} 
+0

我不确定我是否理解......你能举出一个例子吗? – Blake 2013-03-28 00:10:13

+0

非常感谢编辑,我想我可以解决这个问题。 – Blake 2013-03-28 00:25:19

+0

这应该是“......对队列的受保护的内部...” – 2016-09-01 11:39:41

如果你使用你自己写一个队列类,添加一个迭代器。如果您使用的已有迭代器的队列类,请遍历它以打印它。如果您使用的是没有迭代器的队列类,请切换到不同的队列类。

如果您使用的是std::queue,请切换到std::liststd::deque

an examplecplusplus.com演示了如何通过一个deque遍历:

#include <iostream> 
#include <deque> 

int main() 
{ 
    std::deque<int> mydeque; 

    for (int i=1; i<=5; i++) mydeque.push_back(i); 

    std::cout << "mydeque contains:"; 

    std::deque<int>::iterator it = mydeque.begin(); 

    while (it != mydeque.end()) 
    std::cout << ' ' << *it++; 

    std::cout << '\n'; 
    return 0; 
} 

或者:

for (std::deque<int>::iterator it = mydeque.begin(); it != mydeque.end(); ++it) 
    // print *it here 
+0

我不相信我正在使用的类有一个迭代器,我必须坚持这个类的代码(仍然在学校),我怎样才能做到这一点与我目前使用的类? – Blake 2013-03-28 00:03:47

+0

感谢编辑显示的例子,我不得不看看它是否会这样做... – Blake 2013-03-28 00:05:18

+0

@Blake:你不能遍历'std :: queue'。如果你必须使用'std :: queue',你不能迭代它。 – 2013-03-28 00:05:20

如果队列是你自己的代码,并假设你可以在内部迭代它的元素,你可以给它一个friend ostream& operator<<(ostream&, const your_queue_type&)并将这些元素写入输出流。

class Queue 
{ 
public: 
    // methods 
friend ostream& operator<<(ostream& o, const Queue& q) 
{ 
    // iterate over nodes and stream them to o: o << some_node and so on 
} 
}; 

然后

Queue q = ....; 
std::cout << q << std::endl; // calls your ostream& operator<< 

我不知道这是多么有用的,但因为你重视每一个节点到下一个使用nodeType<Type>.link,那么你可能需要做这样的事情:

int numberPrinted = 1; 
nodeType<Type> *temp; 
if (queueFront != NULL) 
{ 
    temp = queueFront; 
    do 
    { 
     cout << numberPrinted << ": " << temp->info << "\n"; 
     numberPrinted++; 
    }while(temp->link!=NULL); 
} 

这样你就可以按照指针而不改变你的队列。