我的Remove函数出了什么问题

What is wrong with my Remove Function?

本文关键字:什么 问题 Remove 函数 我的      更新时间:2023-10-16

在我的中

int队列::remove(int x)

成员函数,用户可以输入一个数字,如果在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;
}

当然会崩溃。如果找不到编号,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是有效的,而它不是。添加一个temp != NULL &&和您应该设置的测试。

当号码不在队列中时。循环的退出条件是在上一个if语句中用CCD_ 2满足的。您用temp->x==n取消引用temp,因为在这种情况下temp为null,您的程序将崩溃。您可以在if temp != null && temp->x==n 中添加一个检查