简体   繁体   English

使队列数据结构作为数组实现的问题

[英]issue in making Queue data structure as array implementation

this code to make simple queue data structure as array implementation 该代码使简单的队列数据结构作为数组实现

#include <stdio.h>
#define Q_MAX_SIZE 255
#include <stdbool.h>
struct queue
{
    int* pointer;
    int* currentValue;
    int max, count, theQueue[Q_MAX_SIZE];
};

void initQueue(struct queue*);
bool pushQueue(struct queue*, int);
int* popQueue(struct queue*);

int main(void)
{
    int i, j, num = 0;
    struct queue obj[5];

    for(i=0; i<5; i++)
    {
        initQueue(&obj[i]);

        for(j = 0; j<3; j++)
        {
            num++;
            pushQueue(&obj[i], num);
        }
        num = 0;
    }

    for(i=0; i<5; i++)
    {
        printf("Queue[%d]:\n", i);
        int* inputobj;
        inputobj = popQueue(&obj[i]);

        while(inputobj != NULL)
        {
            printf("Queue[No.%d] = %d\n", i, *inputobj);
            inputobj = popQueue(&obj[i]);
        }
        putchar('\n');
    }

    puts("done..!");

    return 0;
}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

void initQueue(struct queue *Q)
{
    Q->pointer = Q->theQueue;
    Q->max = Q_MAX_SIZE;
    Q->count = 0;
}

bool pushQueue(struct queue *Q, int input)
{
    if(Q->count < Q->max)
    {
        *Q->pointer = input;
        Q->pointer++;
        Q->count++;
        return 1;
    }
    else
        return 0;
}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

int* popQueue(struct queue *Q)
{
    int i;
    if(Q->count > 0)
    {
        Q->currentValue = Q->theQueue;
        Q->pointer--;
        Q->count--;

        for(i=0; i < Q->count; i++)
        {
            int* currentPtr = Q->theQueue + i;
            int* nextPtr = currentPtr + 1;
            *currentPtr = *nextPtr;
        }
        return Q->currentValue;
    }

    else
        NULL;
}

there is a problem with the code in the function popQueue() in this line: 此行中的函数popQueue()中的代码有问题:

Q->currentValue = Q->theQueue;

it is work put the output is not correct 这是工作把输出不正确

output:
Queue[0]:
Queue[No.0] = 2
Queue[No.0] = 3
Queue[No.0] = 3

Queue[1]:
Queue[No.1] = 2
Queue[No.1] = 3
Queue[No.1] = 3

Queue[2]:
Queue[No.2] = 2
Queue[No.2] = 3
Queue[No.2] = 3

Queue[3]:
Queue[No.3] = 2
Queue[No.3] = 3
Queue[No.3] = 3

Queue[4]:
Queue[No.4] = 2
Queue[No.4] = 3
Queue[No.4] = 3

done..!

but after i change the pointer ( currentValue ) in the queue struct to make it of type integer and edit some lines in the function popQueue() every thing work fine. 但是在更改queue结构中的指针( currentValue )以使其为整数类型并在函数popQueue()编辑一些行之后,一切正常。

--here is the function after editing: -这是编辑后的功能:

int* popQueue(struct queue *Q)
{
  int i;
  if(Q->count > 0)
  {
    Q->currentValue = Q->theQueue[0];
    Q->pointer--;
    Q->count--;

    for(i=0; i < Q->count; i++)
    {
      int* currentPtr = Q->theQueue + i;
      int* nextPtr = currentPtr + 1;
      *currentPtr = *nextPtr;
    }
    return &Q->currentValue;
  }

-- and this is the correct output: -这是正确的输出:

Queue[0]:
Queue[No.0] = 1
Queue[No.0] = 2
Queue[No.0] = 3

Queue[1]:
Queue[No.1] = 1
Queue[No.1] = 2
Queue[No.1] = 3

Queue[2]:
Queue[No.2] = 1
Queue[No.2] = 2
Queue[No.2] = 3

Queue[3]:
Queue[No.3] = 1
Queue[No.3] = 2
Queue[No.3] = 3

Queue[4]:
Queue[No.4] = 1
Queue[No.4] = 2
Queue[No.4] = 3

The Question is: what makes the first code provide wrong output? 问题是:什么使第一个代码提供错误的输出?

What gave you the wrong output in the first case was the fact that the pointer Q->currentValue never changed its value (the address which it was holding). 在第一种情况下,给您错误的输出的事实是指针Q->currentValue从未更改其值(它所保存的地址)。 It was always pointing to the first element in the queue. 它总是指向队列中的第一个元素。

Say the queue contained {1, 2, 3 |,<garbage>} . 说队列包含{1, 2, 3 |,<garbage>}

That means, that after the first pop, the queue became: 这意味着,第一次弹出后,队列变为:

{2, 3 |, 3, <garbage>}

and currentValue still held the address of the first element in the array, which is 2 . 并且currentValue仍然保留数组中第一个元素的地址,即2

After the second pop: 在第二次弹出后:

{3 |, 3, 3, <garbage>}

and currentValue points to the first element, which value is 3 , 并且currentValue指向第一个元素,值为3

The last time, the array is unchanged (as Q->count-- changes Q->count 's value to 0), so the conent is 上一次,数组未更改(因为Q->count--Q->count的值更改为0),所以该内容为

{| 3, 3, 3, <garbage>} {| 3, 3, 3, <garbage>} and currentValue is still pointing to a 3 . currentValue {| 3, 3, 3, <garbage>}并且currentValue仍指向3

I assume that you changed the second example to make Queue->currentValue an int . 我假设您更改了第二个示例,以将Queue->currentValueint

This way, it retains the original first element (which is popped). 这样,它将保留原始的第一个元素(已弹出)。

That makes your prints work properly in your test case. 这样一来,您的打印就可以在测试用例中正常工作。

However, 然而,

  • Your implementation will fail if you had a 0 in your queue. 如果您的队列中有0 ,则实现将失败。
  • Your implementation adds needless complexity to the pop operation (O(n)). 您的实现为pop操作(O(n))增加了不必要的复杂性。 It would be much better to implement a cyclic queue, with head and tail . headtail实现一个循环队列会更好。
  • Retaining a copy of the popped element in order to return it would not be my first choice. 保留弹出元素的副本以返回它不是我的首选。 I would suggest implementing an isEmpty() method, check its result in the while loop and while the queue is not empty, simply have pop() return the queue advance its head and return the previous head element. 我建议实现一个isEmpty()方法,在while循环中检查其结果,并且当队列不为空时,只需让pop()返回队列将其head并返回前一个head元素即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM