C中的优先级队列

时间:2012-03-28 23:59:40

标签: c priority-queue

struct node
{
    int id;
    float weight;
};

int find_last(struct node Prio_Q[])
{
    int i = 1;
    while (Prio_Q[i].id != -1)
    {
        i += 1;
    }
    return i;
}

void initialize_Q(struct node Prio_Q[], int size)
{

    int i;

    for (i = 0; i < size; i ++)
    {
        Prio_Q[i].id = -1;
        Prio_Q[i].weight = -1;

    }
    //printf("The queue is %f", Prio_Q[3].weight);
}

void enque_Q(struct node Prio_Q[], struct node node, int size)
{
    int i = find_last(Prio_Q);

    Prio_Q[i].id = node.id;
    Prio_Q[i].weight = node.weight;
    printf("The last index is %d\n", i);
    heapify_up(Prio_Q, i);
}

void heapify_up(struct node Prio_Q[], int i)
{    

    if (Prio_Q[i/2].weight > Prio_Q[i].weight)
    {
        swap_node(Prio_Q,i/2, i);
        heapify_up(Prio_Q, i/2);
    }
}

void swap_node(struct node Prio_Q[], int i, int j)
{
    struct node temp;
    temp = Prio_Q[i];
    Prio_Q[i] = Prio_Q[j];
    Prio_Q[j] = temp;
    //printf("smething has been swapped.\n");
} 

int main(int argc, char *argv[])
{
    struct node node;
    struct node Prio_Q[10];

    int size = 10;
    initialize_Q(Prio_Q, 11);

    node.id = 5;
    node.weight = 11;

    for(int m = 0; m < size+1; m++)
    {
        printf("The %dth element in Que is %d with weight %f.\n", m, Prio_Q[m].id, Prio_Q[m].weight);
    }

}

这是我构建的优先级队列,但是如果你测试代码,你会发现队列会在我真正要求函数执行之前自动将节点添加到它的最后一个索引。

在main函数中,我只让节点有两个值,但我没有将节点排入优先级队列数组。数组会自动将节点添加到最后一个索引,有人可以帮我吗?

提前致谢。

2 个答案:

答案 0 :(得分:4)

欢迎来到C;语言 not 帮助您避免数组访问越界,这是您的代码的一个特殊问题:

来自main()

struct node Prio_Q[10];

int size = 10;
initialize_Q(Prio_Q, 11);

请注意,您使用initialize_Q() size来呼叫11。这意味着您的for循环将导致数组访问超出Prio_Q数组的结尾:

void initialize_Q(struct node Prio_Q[], int size)
{

    int i;

    for (i = 0; i < size; i ++)
    {
        Prio_Q[i].id = -1;      /* BUG when i == 10 */
        Prio_Q[i].weight = -1;

您应该使用#defineenumconst变量将数组的大小存储在一个位置中。这将大大减少写这样的小错误的机会。

您的find_last()例程应该执行某些边界检查数组的大小。这段代码应该可以正常工作,其余代码没有错误。你也可以重新编写这个函数,以确保它没有走出数组的末尾。 (它将如何处理一个完全完整的数组?提示:很差。:)

int find_last(struct node Prio_Q[])
{
    int i = 1;
    while (Prio_Q[i].id != -1)
    {
        i += 1;
    }return i;
}

对于你的输出(它应该是它自己的功能,所以你可以在你的程序中自由地撒上它):

for(int m = 0; m < size+1; m++)
{
    printf("The %dth element in Que is %d with weight %f.\n", m, Prio_Q[m].id, Prio_Q[m].weight);
}

同样,您在m == 10时已经访问了数组的末尾。

答案 1 :(得分:2)

您正在语句struct node Prio_Q[10];中初始化一个大小为10 [索引0,1,..,9]的数组

但是当您初始化队列initialize_Q(Prio_Q, 11);时,您使用大小11初始化它:[0,1,...,10]。你从分配的数组中溢出来了!

稍后在for(int m = 0; m < size+1; m++)

中打印元素时会发生同样的情况

请记住,c数组中的索引是0,所以如果你有n个元素,那么你的索引是[0,1,...,n-1] - 所以你的迭代应该来自i = 0 i < n