2012-02-25 3 views
0

В моейЧто не так с моей функцией удаления?

Int Queue :: Удалить (INT х) функция

член моего класса Queue, который вы найдете ниже, пользователь может ввести номер и, если номер найден в очередь, узел, содержащий номер, удаляется, и возвращаемый номер возвращается. Если номер не найден, выводится «номер не найден» и возвращается нулевой номер. Однако, когда число не найдено, программа просто падает. Кроме того, даже если выход работал, он выглядит немного странным, выводя «0 удаляется ... и т. Д.», Когда на самом деле я имею в виду, что число не было найдено, а не то, что число «0» было найдено и удалено. .

#include <iostream> 
#include <string> 
#include <cassert> 

using namespace std; 

class Dnode 
{ 
    public: 
     Dnode(int); 
     int n; 
     Dnode* l, *r; 
}; 

Dnode::Dnode(int tx) 
{ 
    n = tx; 
    l = r = NULL; 
} 

class Queue // reminder: insertions at the rear, deletions at the front 
{ 
    public: 
     Queue(); 
     void enqueue(int x); 
     int dequeue(); 
     bool empty() const; 
     void display() const; 
     Queue(const Queue&);    // copy constructor 
     ~Queue();      // destructor 
     Queue& operator= (const Queue&); // assignment operator 
     void displayrev() const; 
     int remove(int); 


    private: 
     Dnode* front, *back; 
     void copy(Dnode*); 
     void free(); 

}; 

Queue::Queue() 
{ 
    front = back = NULL; 
} 


void Queue::enqueue(int x) 
{ 
    Dnode* d = new Dnode(x); 
    if (empty()) 
     front = back = d; 
    else 
    { 
     back->r = d; // makes last dnode's right hand point to the new one 
     d->l = back; // makes new dnode's left hand point to the previous last one 
     back = d; // makes back pointer point to the new last dnode 
    } 
} 

int Queue::dequeue() 
{ 
    assert(! empty()); 
    Dnode* temp = front; 
    front = front->r; // moves front pointer one dnode to the right 
    if (front == NULL) // if there was only one dnode in the queue 
     back = NULL; // now both front and back pointers are set to NULL 
    else front->l = NULL; 
    int x = temp->n; 
    delete temp; 
    return x; 
} 


bool Queue::empty() const 
{ 
    return front == NULL; 
} 

void Queue::display() const 
{ 
    for (Dnode* d = front; d != NULL; d = d->r) //front to rear 
     cout << d->n << " "; 
    cout << endl; 
} 

void Queue::displayrev() const 
{ 
    for (Dnode* d = back; d != NULL; d = d->l) // rear to front 
     cout << d->n << " "; 
    cout << endl; 
} 

void Queue::copy(Dnode* dn) //"dn" will be "Front" of Queue being copied 
{ 
    front=back=NULL; 

    if(dn!=NULL) 
    { 
     while(dn->r!=NULL) 
     { 
      enqueue(dn->n); 
      dn=dn->r; 
     } 
     enqueue(dn->n); 
    } 
} 

Queue::Queue(const Queue& x) 
{ 
    copy(x.front); 
} 

void Queue::free() 
{ 
    Dnode* temp=front; 

    while(front!=back) 
    { 
     front=front->r; 
     delete temp; 
     temp=front; 
    } 
    delete temp; 

    front=back=temp=NULL; 
} 

Queue::~Queue() 
{ 
    cout << "Destructor called!"<<endl<<endl; 
    free(); 
} 

Queue& Queue::operator= (const Queue& x) 
{ 
    if(this!=&x) 
    { 
     free(); 
     copy(x.front); 
    } 
    return *this; 
} 

int Queue::remove(int x) //<--- Here we are... 
{ 
    Dnode* temp=front; 

    if(front->n==x) // if the node being deleted is the first node 
    { 
     front=front->r; 
     if(front==NULL) // if there is only one node in the Queue 
     { 
      back=NULL; 
     } 
     else 
     { 
      front->l=NULL; 
     } 
     delete temp; 
     return x; 
    } 

     Dnode* pre; 

    while(temp!=NULL && temp->n!=x) // order of conditions is important! 
    { 
     pre=temp; 
     temp=temp->r; 
    } 

    if(back->n==x) // if the node being deleted is the last node 
    { 
     back=pre; 
     back->r=NULL; 
     delete temp; 
     return x; 
    } 

    if(temp->n==x) // deleting from the middle 
    { 
     pre->r=temp->r; 
     temp->r->l=pre; 
     delete temp; 
     return x; 
    } 

    cout<<"Number not found! ";// if number is not found, function should 
    return 0;     // return number 0, but it doesn't, instead 
}        // it crashes the program 
           // check out my output for this function in main() below     
           // as well.. 
int main() 
{ 
    Queue q; 

    if (q.empty()) cout << endl<<"Queue \"q\" is empty" << endl; 

    for (int i = 0; i < 10; i++) q.enqueue(i); 

    cout<<endl<<"Queue \"q\" is now populated"<<endl<<endl<<"Queue \"q\" : "; 

    q.display(); 

    int x = q.dequeue(); 

    cout <<endl<<"First element of \"q\" has been removed from the front" << endl; 

    cout << endl<<"Element removed is " << x << endl; 

    cout<<endl<<"Queue \"q\" : "; 

    q.display(); 

    Queue q1(q); 

    cout<<endl<<"Queue \"q1\" has been created as a copy of \"q\""<<endl<<endl; 

    cout<<"Queue \"q1\" : "; 

    q1.display(); 

    Queue q2=q1; 

    cout<<endl<<endl<<"Queue \"q1\" has been assigned to new Queue \"q2\""<<endl<<endl; 

    cout<<"Queue \"q2\" : "; 

    q2.display(); 

    q1=q1; 

    cout<<endl<<endl<<"\"q1\" has been assigned to itself and what we get is: "; 

    q1.display(); 

     cout<<endl<<"\"q1\" displayed in reverse: "; 

    q1.displayrev(); 

    cout<<endl<<"type in a number to remove from \"q1\": "; 

    int y; 

    while(cin>>y) 
    { 
     cout<<endl<<q1.remove(y)<<" has been removed from \"q1\" "<<"type in    
       another one or q to quit: "; 
    } 

    /* 
    if the number is not found, the above "cout" should look like this : 

    "Number not found! 0 has been removed from "q1" type in another one or q to quit: " 

    However, this is not the case and the program crashes when number is not found 
    */ 


    cout<<endl<<"Queue \"q1\" : "; 

    q1.display(); 

    cout<<endl; 
} 
+2

Голосовать за закрытие: вы можете решить эту проблему (или хотя бы изолировать более конкретную проблему) с помощью отладчика. –

+0

Угадайте, что вы правы, я думаю, что на самом деле я нашел ошибку, это мой предварительный указатель, который остался неинициализированным в некоторых случаях, я думаю, но не в том случае, когда этого числа нет. Так что это не должно быть проблема..о хорошо .. –

ответ

0

Конечно, это произойдет сбой. В случае, когда номер не найден, цикл while будет перебираться полностью на «назад» в очереди, а temp будет NULL.

Dnode* pre; 

while(temp!=NULL && temp->n!=x) // order of conditions is important! 
{ 
    pre=temp; 
    temp=temp->r; 
} 

Как только это произойдет, вы делаете:

if(temp->n==x) // deleting from the middle 
{ 

с предположением о том, что температура является действительным, если его нет. добавьте тест temp != NULL &&, и вы должны быть установлены.

+0

Вы правы! Это должно быть beem: if (temp! = NULL && temp-> n == x) Спасибо! –

+0

Только один последний вопрос. Даже если номер не находится в очереди, я хочу вернуть номер, и в этом случае я возвращаю «0». Что произойдет, если вход «0», а номер в очереди? Я не могу различать эти два и выходные данные сбивать с толку, я мог бы использовать Exit, если номер не найден, но это приведет к сбою всей программы. Какие-либо предложения? –

+0

Возвращает указатель на DNode, и если его не NULL, прочитайте его номер и распечатайте его, а затем удалите dnode. – astevanovic

0

Когда номер не находится в очереди. условие выхода для вашего цикла удовлетворено temp == null в вашем последнем операторе if, где вы устанавливаете временную разницу с temp->x==n, так как в этом случае temp имеет значение null, программа сработает. Вы можете добавить чек, если temp != null && temp->x==n

+0

спасибо, ты был прав! :) –

Смежные вопросы