c-处理2个队列的出队列函数遇到segfault



下面的函数应该将由2个队列组成的结构出列。每次我们将第一个队列出列时,它的后面需要变成第二个队列的前面。从本质上讲,将第二队列中的第一元素移动到第一队列以作为其后方。我想出了下面的算法:

int dequeue(queue* Q1,queue* Q2){
node* temp;
if(Q1->rear=NULL){
return 0;
}
if(count<3){
temp=Q1->front;
Q1->front=Q1->front->next;
free(temp);
count--;
return 1;
}
if(count>=3){
temp=Q1->front;
Q1->front=Q1->front->next;
free(temp);
Q1->rear->next=Q2->front;
Q1->rear=Q1->rear->next;
Q2->front=Q2->front->next;
Q1->rear->next=NULL;
if(Q2->front=NULL){
Q2->rear=NULL;
}
count--;
return 1;
}
}

它在Q1->rear->next=Q2->front;上给出一个segfault

有其他方法可以实现这一点吗?

对于初学者来说,if语句的条件中有一个拼写错误

if(Q2->front=NULL){
Q2->rear=NULL;
}

您使用的是赋值而不是比较。

这个if语句中也有一个错误

if(count<3){
temp=Q1->front;
Q1->front=Q1->front->next;
free(temp);
count--;
return 1;
}

此语句后的q1-front

Q1->front=Q1->front->next;

可以等于CCD_ 3。在这种情况下,还需要将Q1->rare设置为NULL

但在任何情况下,您使用if语句的方法

if(count<3){
temp=Q1->front;
Q1->front=Q1->front->next;
free(temp);
count--;
return 1;
}
if(count>=3){
temp=Q1->front;
Q1->front=Q1->front->next;
free(temp);
//...

使得代码不那么清晰,并且在发生错误时很容易出错。

我会用以下方式编写函数

int dequeue( queue *q1, queue *q2 )
{
int success = q1->front != NULL;
if ( success )
{
if ( q2->front != NULL )
{
q1->rear->next = q2->front;
q1->rear = q1->rear->next;  
q2->front = q2->front->next;
if ( q2->front == NULL ) q2->rear = NULL;
q1->rear->next = NULL;
}
node *tmp = q1->front;
q1->front = q1->front->next;
if ( q1->front == NULL ) q1->rear = NULL;
free( tmp );
--count;
}
return success;
}

请注意,当函数依赖于全局变量(我指的是变量count(时,这是一种糟糕的编程实践。您可以避免在结构中包装队列和变量count的这种情况。

这是一个演示程序,展示了该功能的作用。

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} node;
typedef struct queue
{
node *front;
node *rear;
} queue;
size_t count;
int dequeue( queue *q1, queue *q2 )
{
int success = q1->front != NULL;
if ( success )
{
if ( q2->front != NULL )
{
q1->rear->next = q2->front;
q1->rear = q1->rear->next;  
q2->front = q2->front->next;
if ( q2->front == NULL ) q2->rear = NULL;
q1->rear->next = NULL;
}
node *tmp = q1->front;
q1->front = q1->front->next;
if ( q1->front == NULL ) q1->rear = NULL;
free( tmp );
--count;
}
return success;
}
int push( queue *q, int data )
{
node *new_node = malloc( sizeof( node ) );
int success = new_node != NULL;

if ( success )
{
new_node->data = data;
new_node->next = NULL;

if ( q->rear == NULL )
{
q->front = new_node;
}
else
{
q->rear->next = new_node;
}

q->rear = new_node;

++count;
}

return success;
}
int empty( const queue *q )
{
return q->front == NULL;
}
int front( queue *q )
{
return q->front->data;
}
int main( void )
{
queue q1 = { .front = NULL, .rear = NULL };  
queue q2 = { .front = NULL, .rear = NULL };  

const int N = 10;

for ( int i = 0; i < N; i++ )
{
if ( i < N / 2 ) push( &q1, i );
else push( &q2, i );
}

while ( !empty( &q1 ) )
{
printf( "%d ", front( &q1 ) );
dequeue( &q1, &q2 );
}

putchar( 'n' );
for ( int i = 0; i < N; i++ )
{
if ( i < N / 2 ) push( &q1, i );
else push( &q2, i );
}

while ( !empty( &q1 ) )
{
printf( "%d ", front( &q1 ) );
dequeue( &q1, &q2 );
}

putchar( 'n' );
}

程序输出为

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9

有相同的代码被执行两次,以表明函数dequeue工作正常。

最新更新