【问题标题】:Why is my code printing "The queue is empy" after displaying the queue once为什么我的代码在显示队列后打印“队列为空”
【发布时间】:2021-09-27 14:59:43
【问题描述】:

我忘记在 display() 方法的开头添加一个临时节点,但后来我添加了它,但我仍然面临同样的问题。我无法在我的代码中找到问题。

我在下面添加了完整的代码:

#include <stdio.h>
#include <stdlib.h>

struct Node
{
    int key;
    struct Node* next;
};

struct Queue
{
    struct Node *front, *rear;
};

struct Node* newNode(int k)
{
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    temp->key = k;
    temp->next = NULL;
    return temp;
}

struct Queue* createQueue()
{
    struct Queue* q = (struct Queue*)malloc(sizeof(struct Queue));
    q->front = q->rear = NULL;
    return q;
}

void enQueue(struct Queue* q, int k)
{
    struct Node* temp = newNode(k); 
    if (q->rear == NULL)
    {
        q->front = q->rear = temp;
        return;
    }
    q->rear->next = temp;
    q->rear = temp;
}
void deQueue(struct Queue* q)
{
    if (q->front == NULL)
    {
        printf("The Queue is empty.\n");
        return;
    }
    struct Node* temp = q->front;
    printf("Deleted Element: %d\n",q->front->key);
    q->front = q->front->next;
    if (q->front == NULL)
        q->rear = NULL;
    free(temp);
}
void display(struct Queue* q)  
{  
    struct Queue* temp=q;
    if(temp->front == NULL)  
    {  
        printf("The Queue is Empty.\n");  
    }  
    else  
    {   
        printf("Queue contains the following elements:\n");  
        while(temp->front != NULL)
        {  
            printf("%d\t",temp->front -> key);  
            temp->front = temp->front -> next;  
        }
        printf("\n");
    }  
}  

int main()
{
    struct Queue* q = createQueue();
    int choice=0;     
    while(choice != 4)  
    {  
        printf("Choose from the following by entering the index number:\n1.Insert an element\n2.Delete an element\n3.Display the elements in queue\n4.Exit\n");  
        scanf("%d",&choice);  
        switch(choice)  
        {  
            case 1:  
            {   
                int k;
                printf("Enter the element you want to insert: ");
                scanf("%d",&k);  
                enQueue(q,k);
                break;  
            }  
            case 2:  
            {  
                deQueue(q); 
                break;  
            }  
            case 3:  
            {  
                display(q);  
                break;  
            }  
            case 4:   
            {  
                printf("\nThe program has ended."); 
                exit(0); 
                break;   
            }  
            default:  
            {  
                printf("\nInvalid Input! Please try again.");  
            }
        }
    }
}

【问题讨论】:

    标签: c pointers struct while-loop queue


    【解决方案1】:

    在您的display 函数中,您认为这行代码的作用是什么?

    temp->front = temp->front -> next;
    

    它会向前移动队列的前端,直到最终指向NULL。因为您不会通过将 q 分配给 temp 来制作队列的另一个副本 - 它们都指向同一个队列。

    相反,您要做的是使 temp 成为 struct Node 并将其沿队列移动 - 像这样

    void display(struct Queue* q)  
    {  
        struct Node* temp=q->front;
        if(temp == NULL)  
        {  
            printf("The Queue is Empty.\n");  
        }  
        else  
        {   
            printf("Queue contains the following elements:\n");  
            while(temp != NULL)
            {  
                printf("%d\t",temp -> key);  
                temp = temp -> next;  
            }
            printf("\n");
        }  
    } 
    

    【讨论】:

      【解决方案2】:

      对于初学者来说,为新模式分配内存可能会失败。在这种情况下,您的代码将调用未定义的行为。改写函数newNode如下

      struct Node * newNode( int k )
      {
          struct Node *temp = malloc( sizeof( struct Node ) );
      
          if ( temp != NULL )
          {
              temp->key = k;
              temp->next = NULL;
          }
      
          return temp;
      }
      

      相应的函数enQueue应该改写如下

      int enQueue( struct Queue *q, int k )
      {
          struct Node *temp = newNode( k );
          int success = temp != NULL;
       
          if ( success )
          {
              if ( q->front == NULL)
              {
                  q->front = temp;
              }
              else
              {
                  q->rear->next = temp;
              }
      
              q->rear = temp;
          }
      
          return success;
      }
      

      函数deQueue 不应发出任何消息。决定是否发出消息的是函数的调用者。 您可以再编写一个函数来报告队列是否为空。例如

      int isEmpty( const struct Queue *q )
      {
          return q->front == NULL;
      }
      

      函数deQueue可以这样定义

      void deQueue( struct Queue *q )
      {
          if ( !isEmpty( q )
          {
              struct Node *temp = q->front;
      
              q->front = q->front->next;
              if ( q->front == NULL ) q->rear = NULL;
      
              free( temp );
          }
      }
      

      并且函数可以像这样调用

      case 2:
      {
          if ( isEmpty( q ) )
          {
              printf("The Queue is empty.\n");
          }
          else
          {
              printf("Deleted Element: %d\n",q->front->key);
              deQueue( q );
          }
      }
      

      在这个赋值后的函数display

      struct Queue* temp=q;
      

      指针temp 指向与指针q 相同的struct Queue 类型的对象。也就是说,您正在使用两个不同的指针访问同一个对象。因此,使用指针 temp 您正在更改 struct Queue 类型的原始对象

      temp->front = temp->front -> next;  
      

      所以在这个循环之后

      while(temp->front != NULL)
      

      struct Queue 类型的原始对象的指针front 将等于NULL。

      函数可以通过以下方式定义

      void display( const struct Queue *q )  
      {  
          printf("Queue contains the following elements:\n");  
      
          for ( const struct Node *current = q->front; current != NULL; current = current->next;)
          {  
              printf( "%d\t", current->key);  
          }
          printf("\n");
      }  
      

      并且函数可以像这样调用

      case 3:
      {
          if ( isEmpty( q ) )
          {
              printf( "The Queue is Empty.\n" );
          }
          else
          {
              display( q );
          }
      }
      

      【讨论】:

      • 非常感谢,它对我有用!我应该看到我使用的是原来的前端节点?
      • @anish-saraogi 完全没有。不客气。:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多