为什么我的代码在显示队列一次后打印 "The queue is empy"
Why is my code printing "The queue is empy" after displaying the queue once
我忘记在 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.");
}
}
}
}
在您的 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");
}
}
对于初学者来说,为新模式分配内存可能会失败。在这种情况下,您的代码将调用未定义的行为。将函数 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 );
}
}
我忘记在 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.");
}
}
}
}
在您的 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");
}
}
对于初学者来说,为新模式分配内存可能会失败。在这种情况下,您的代码将调用未定义的行为。将函数 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 );
}
}