【问题标题】:Sorting structures in a linked list based on the values of two fields根据两个字段的值对链表中的结构进行排序
【发布时间】:2021-05-16 08:40:39
【问题描述】:

我想对优先级队列中具有相同优先级的值进行排序。一切都是从一个简单的 .txt 文件加载的。我已经对所有优先级进行了排序,但现在我想对具有相同优先级的值进行排序。

我的代码比较简单。它有推送和弹出功能,你猜对了,推送和弹出哈哈。

函数ispis是为打印而生的。我也知道声明一个虚拟节点不是一个好主意,但他们在大学教我们这样,所以我很适应它。

这是我想如何对元素进行排序的示例:

例如

10 1 
2 1
3 1

2 1 
3 1
10 1 

我的代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct cvor* Red;
struct cvor {
    int el, pr;
    Red next;
};
void push(Red R, int b, int p);
void print(Red R);
void pop(Red R);

int main() {
    FILE* dat;
    int br, pr;
    struct cvor Head;
    Head.next = NULL;
    dat = fopen("redsp.txt", "r");

    if (!dat) {
        printf("No file!\n");
    }
        
    while (fscanf(dat, "%d %d", &br, &pr) != EOF) {
        push(&Head, br, pr);
    }
        
    printf("Printing:\n");
    print(Head.next);

    /*printf("\n\n\n");
    printf("poppin:D\n");
    for (int i = 0; i < 14;i++) {
        pop(&Head);
        printf("\n\n\n");
        print(Head.next);
    }*/

    fclose(dat);    
}

void push(Red R, int b, int p) {
    Red q;
    q = (Red)malloc(sizeof(struct cvor));

    q->el = b;
    q->pr = p;

    /*if (q->pr >p) {
        q->next = R;
        R = q;
    }*/

        while (R->next != NULL && R->next->pr < p)
        {   
            R = R->next;
        }
            
        q->next = R->next;
        R->next = q;    
    
}

void pop(Red R) {
    Red temp, pre;
    temp = R->next;
    pre = NULL;

    while (temp && temp->next) {
        pre = temp;
        temp = temp->next;
    }
    if (pre) {
        free(pre->next);
        pre->next = NULL;
    }

}


void print(Red R) {
    while (R != NULL)
    {
        printf("%d %d\n", R->el, R->pr);
        R = R->next;
    }
}

【问题讨论】:

  • 如果您对相应的变量、函数参数和结构字段使用相同的名称,代码会更容易理解。我建议edit 您的问题,并在两列中使用不同的值扩展示例输入,并显示当前结果和预期结果。我想你的问题基本上是如何根据比较两个值对数据进行排序,即如何替换 while (R-&gt;next != NULL &amp;&amp; R-&gt;next-&gt;pr &lt; p) 来比较两个元素。
  • @Bodo 我编辑了我的代码。嗯,是的,你可以这样称呼它。有没有办法制作这种算法?

标签: c linked-list queue priority-queue


【解决方案1】:

据我了解您的问题,问题是如何根据两个值比较数据。

线

    while (R->next != NULL && R->next->pr < p)

检查列表的末尾并比较节点结构的一个字段。

为了使代码更清晰,我建议将比较替换为函数调用。

void push(Red R, int b, int p) {
    Red q;
    q = (Red)malloc(sizeof(struct cvor));

    q->el = b;
    q->pr = p;

    while (R->next != NULL && compare_nodes(R->next, q) < 0)
    {   
        R = R->next;
    }
            
    q->next = R->next;
    R->next = q;    
}

您当前的比较可以实现为

/**
 * Compare two nodes.
 *
 * This implementation compares only the pr fields.
 *
 * @param a Pointer to node A.
 * @param b Pointer to node B.
 *
 * @retval <0 if A < B
 * @retval 0  if A == B
 * @retval >0 if A > B
 */
int compare_nodes(const struct cvor *a, const struct cvor *b) {
    /* here only the "pr" element is compared */
    int retval = a->pr - b->pr;
    return retval;
}

您可以扩展该函数以比较其他结构字段,如果 第一个字段的比较结果是“相等”。

int compare_nodes(const struct cvor *a, const struct cvor *b) {
    /* compare pr field first */
    int retval = a->pr - b->pr;
    /* compare el field if necessary */
    if (retval == 0) retval = a->el - b->el;
    return retval;
}

请注意,在生产代码中,函数应确保参数不是 NULL 指针,而不是依赖于调用者。

【讨论】:

  • 感谢您的宝贵时间,但不幸的是,这并没有解决我的问题。
  • 这是我文件中的内容: 1 2 3 4 5 2 4 3 9 1 4 1 1 1 3 2 5 1 6 2 10 1 2 2 3 2 所以你可以把它放在你的编译器自己看吧。
  • @JackJones 请编辑您的问题以显示您的真实输入并将其格式化为代码块。显示您通过程序获得的输出以及您想要获得的预期输出。
  • 我的代码中有一个错字:if (retval = 0) 必须是 if (retval == 0)。你的编译器应该已经显示了一个警告。
  • @JackJones 如果您的编译器没有显示警告,您可能必须启用所有警告。见stackoverflow.com/q/57842756/10622916
猜你喜欢
  • 2020-04-10
  • 2014-01-27
  • 2019-05-21
  • 1970-01-01
  • 2016-08-25
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
相关资源
最近更新 更多