【问题标题】:Priority queue not inserting element in ascending order优先队列未按升序插入元素
【发布时间】:2018-10-03 14:30:29
【问题描述】:

这是使用链表的优先队列的代码 我对这段代码有两个疑问

1) 这段代码是我的插入函数的一部分

 if((*addofhead)->priority <= newnode->priority ){
    struct node* temp=*addofhead;
    while(temp->next!=NULL&&temp->priority <newnode->priority ){
        temp=temp->next;
    }
    newnode->next=temp->next;
    temp->next=newnode;
    return;
   }

为什么我们不能在 while 循环而不是 temp-&gt;next!=NULL 中执行 temp!=NULL ,因为 temp!=NULL 也会在另一次迭代中退出循环,但它正在崩溃 崩溃的原因是什么

2)我想创建一个优先级队列,使得具有最低优先级的元素 应该首先删除并且具有相同优先级的元素然后将首先删除首先添加的元素 来自main函数的输入部分

    insert(&head,3,5);   
    insert(&head,2,2);   

    insert(&head,1,1);   
    insert(&head,7,1);
    insert(&head,11,1);
    insert(&head,8,5);   
    insert(&head,9,5);

我得到了这个1 2 11 7 3 8 9 的输出,但它的输出应该是1 7 11 2 3 8 9

#include<stdio.h>
#include<stdlib.h>
struct node{
    int data;
    int priority;
    struct node* next;
};
struct node* getnewnode(int data,int priority){
    struct node* newnode=malloc(sizeof(struct node));
    newnode->data=data;
    newnode->next=NULL;
    newnode->priority=priority;
    return newnode;
}
void insert(struct node** addofhead,int data,int priority){

    struct node* newnode=getnewnode(data,priority);
    if(*addofhead==NULL){
        *addofhead=newnode;
        printf("head in insert is %d",*addofhead);
        return;
    }

    if((*addofhead)->priority > newnode->priority){
        newnode->next=*addofhead;
        *addofhead=newnode;
        return;
    }

    if((*addofhead)->priority <= newnode->priority ){
        struct node* temp=*addofhead;
        while(temp->next!=NULL&&temp->priority <newnode->priority ){
            temp=temp->next;
        }
        newnode->next=temp->next;
        temp->next=newnode;
        return;
    }
}
int removee(struct node** head){
    if(*head==NULL)
        return -1;
    int temp=(*head)->data;
    *head=(*head)->next;
    return temp;
}
int main(){
    struct node* head=NULL;
    insert(&head,3,5);   /// 3
    insert(&head,2,2);   /// 2,3

    insert(&head,1,1);   /// 1,2,3
    insert(&head,7,1);
    insert(&head,11,1);
    insert(&head,8,5);   /// 1,7,2,3
    insert(&head,9,5);
    struct node* temp=head;
    while(temp)
    {
        printf(" %d ",temp->data);
        temp=temp->next;

    }
    printf("\n head in main  after insertion is %d",head);

}

【问题讨论】:

  • (1) 如果循环在temp == NULL 时中断,则循环后的赋值temp-&gt;next = newnode; 是错误的(与之前的赋值中对temp-&gt;next 的先前引用一样)。
  • 您的插入代码在具有该优先级的第一个项目之后以相反的顺序插入新的同等优先级项目。您应该将 PQ 打印代码制作成一个函数,该函数接受一个标签字符串(以识别它是哪个调用)和头指针,并且您应该打印出数据和优先级。并且,为了怜悯,在printf() 语句中用换行符结束消息——至少在printf("head in insert is %d",*addofhead); 这样的上下文中。并使用%p 打印地址,将相应的参数转换为void *(因为%p 需要void *)。另外,删除removee(),因为它未使用。
  • @wildplasser:我同意Pointer is not modifying in insert in C 是一个密切相关的问题,尽管是由不同的用户提出的。但是,它不是完全重复的;它处理的是这里讨论的一个前兆问题。为什么这两个问题都获得了多次投票有点神秘。它们不是坏问题,但也不是那么好。所以,虽然密切相关,但我不认为这是重复的。
  • @JonathanLeffler removee() 错字怎么样?
  • @wildplasser:removee() 函数没有被使用,所以我忽略了它——我在测试时删除了它。我同意代码几乎肯定是由同一个人(至少是同一个团队)编写的,尽管 SO 用户名不同;它太相似了。然而,要解决的问题是不同的,所以问题不是严格的重复。这是另一个的推论或后续;在上一个问题得到解决之前,无法提出这个问题。

标签: c data-structures queue


【解决方案1】:

为什么我们不能在 while 循环中使用 temp!=NULL 而不是 temp-&gt;next!=NULL (?)

因为循环后面的行有temp-&gt;next;@Jonathan Leffler

沿着链表进行插入的通常目标是知道前一个节点的指针,以便更新其.next成员。


代码有 2 个功能问题

比较错误的优先级

// while(temp->next!=NULL&&temp->priority <newnode->priority ){
while(temp->next!=NULL&&temp->next->priority <newnode->priority ){
//                          ^^^^^^    

== 时比较错误

// while(temp->next!=NULL&&temp->next->priority <newnode->priority ){
while(temp->next!=NULL&&temp->next->priority <= newnode->priority ){
//                          ^^^^^^           ^^

也可以使用%p 来打印void *,而不是"%d" 来打印指针。

// printf("head in insert is %d",*addofhead);
printf("head in insert is %p",(void *) (*addofhead));

对此非常有用的是创建一个辅助函数来打印数据。每次插入后都可以轻松调用它以缩小问题范围。

void pq(const struct node* p) {
  while (p) {
    printf("(data %d,pri %d) ", p->data,  p->priority);
    p = p->next;
  }
  puts("");
}

我发现 OP 的 insert() 过于复杂。见@wildplasser

【讨论】:

  • 另请参阅wildplasseranswer 相关问题以重写insert
  • @JonathanLeffler 是的,这样更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
相关资源
最近更新 更多