在C中制作一个计算PriorityQueue中元素数量的函数

Posted

技术标签:

【中文标题】在C中制作一个计算PriorityQueue中元素数量的函数【英文标题】:Making a function that counts number of elements in PriorityQueue in C 【发布时间】:2020-01-21 11:10:10 【问题描述】:

任务: 我正在为我的结构和算法大学课程做作业。任务是使用堆在 C 中实现优先级队列并形成 main 以便它可以支持以下操作:INSERT s(在优先级队列中插入字符串)DELETE(删除优先级最低的元素)NUMBER(返回优先级队列中的元素数)我们还应该打印出来每次我们在 main 中编写操作时,优先级队列的预排序。我们可以假设堆是用指针实现的。所以我以如下结构实现了它:

typedef char* elementtype;

typedef struct celltag 
    elementtype zapis;
    struct celltag *left, *right, *parent;
   celltype;

typedef celltype* node;
typedef celltype* PriorityQueue;

我还实现了以下功能:

void PrMakeNull(PriorityQueue *Ap)
int PrEmpty(PriorityQueue A)
void PrInsert(elementtype x, PriorityQueue *Ap)
elementtype PrDeleteMin(PriorityQueue *Ap)
void Preorder(PriorityQueue A)

问题: 我应该用这样的标题实现“数字函数”:

int Number(PriorityQueue P)

该函数在调用 Number(A) 后不应更改优先队列 A。此外,该功能应该独立于优先队列实现。 (我认为这意味着我应该只使用 PrMakeNull、PrEmpty、PrInsert、PrDeleteMin)。这甚至可能吗?我怎么能做到?它应该是什么样子?我尝试了什么:1)

//This one is independent on Priority Queue implementation but destroys the Priority Queue. 
int Number(PriorityQueue P)
    PriorityQueue S;
    PrMakeNull(&S);
    int counter=0;
    while(!PrEmpty(P))
    
        PrInsert(PrDeleteMin(&P), &S);
        counter++;
    
    while(!PrEmpty(S))
    
        PrInsert(PrDeleteMin(&S), &P);
    
    return counter;

2)

//This one is dependent on Priority Queue implementation but doesn't destroy the Priority Queue. 
int Number(PriorityQueue A)
    int returning_number=1;
    if (A == NULL)
        return 0;
    if(A->left!=NULL)
        returning_number+=Number(A->left);
    if(A->right!=NULL)
        returning_number+=Number(A->right);
    return returning_number;

【问题讨论】:

“我认为这意味着......” - 那你应该问问你的老师。 那他不应该给我半功课的答案吗?我想我必须这样做...... 您可能想阅读此内容。不要用 typedef 隐藏结构和指针。 ***.com/a/54752982/6699433 您的队列似乎是一棵树(不是队列)。 这是通过堆实现的优先队列(二叉树的一种) 【参考方案1】:

您可以使用不依赖于您列出的函数的递归算法来解决此问题。 代码可能是这样的:

int Number(PriorityQueue A)

    if(!A) return 0;

    return 1 + Number(A->left) + Number(A->right);

我认为这是解决这个问题的最佳方法。

如果您在递归方面遇到问题,我会给您一个有用的链接:

recursion

编辑:

我认为不可能从优先队列的结构中抽象出来,因为PrEmptyPrInsertPrDeleteMinPreorder 的实现已经依赖于优先队列的结构。那么为什么要寻找一个只依赖于这些功能的实现呢?同样为了通用,您可以定义另一个函数来搜索元素而不删除它们,并在上述函数的同一级别实现它,或者更好地在优先级队列上使用简单的迭代器。

【讨论】:

我理解你写的递归。这是我的 2) 代码的较短版本。但是,如果您像这样实现优先级队列,同样的功能也应该起作用(功能应该独立于实现): typedef struct elementtype elements[MAXSIZE] ;最后一个; PriorityQueue; 搜索仅依赖于这些函数的实现在我看来也很愚蠢!但我认为这就是任务。这些函数是我们书中描述优先队列的函数。上次,我的朋友使用了特定于实现的表示法,只得到了 4/8 分。 是的,但我建议你问问你的教授你的解决方案1是否可以,或者你是否可以创建新的辅助功能 我问我的助理,你提供的功能是否足够好。 非常感谢...如果正确请采纳答案【参考方案2】:
int Number(PriorityQueue A) 
    if(PrEmpty(A)) return 0;
    elementType val = PrDeleteMin(&A);
    int num = 1 + Number(A);
    PrInsert(val, &A);
    return num;


【讨论】:

此解决方案会破坏您的队列,就像您在选项 1 代码中所做的那样。 PrDeleteMin(&A) 返回 elementType 的副本并从队列中删除该元素,这样 A 被破坏然后重建,就像您在代码 1 中所做的那样 它改变了 PriorityQueue。

以上是关于在C中制作一个计算PriorityQueue中元素数量的函数的主要内容,如果未能解决你的问题,请参考以下文章

计算机程序的思维逻辑 (46) - 剖析PriorityQueue

java集合类型源码解析之PriorityQueue

在“initialCapacity=n”的“java.util.PriorityQueue”中插入“n”个元素的时间复杂度

java PriorityQueue(优先级队列)

通过键在 PriorityQueue 中查找元素

LeetCode 378. 有序矩阵中第K小的元素 Java