gpt4 book ai didi

c - 双重排序(将元素排序为2个不同的值)

转载 作者:太空宇宙 更新时间:2023-11-04 00:50:35 24 4
gpt4 key购买 nike

假设我有一个结构节点,如下所示:

typedef struct node{
int t;
double p;
}node;

然后我还有一个 struct node数组,其中一些数组的p值相等。
我想做的是:
首先,根据p值对元素进行排序,在得到基于p的排序数组之后,我希望具有相同p的每个子数组都根据t值进行排序。
例如:
如果我有这样的原始数组(第一个元素是p,第二个元素是t):
[0,10 | 1],[0.05 | 0],[0,10 | 0],[0,05 | 2],[0,10 | 2],[0,15 | 1],[0,05 | 1]
经过双重排序后,应该如下所示:
[0,05 | 0],[0,05 | 1],[0,05 | 2],[0,10 | 0],[0,10 | 1],[0,10 | 2],[0,15 | 1]。
我已经提出了基于p的冒泡排序,但是我在如何对t上的子数组排序上遇到了困难。
node *sort_p(node *nodes, int num) {
int i, j;
node *temp = malloc(sizeof(node));

for(i=1; i<num; i+=1){
for(j=0; j<num-i; j+=1){
if(nodes[j].p > nodes[j+1].p){
*temp = nodes[j];
nodes[j] = nodes[j+1];
nodes[j+1] = *temp;
}
}
}
free(temp);

return nodes;
}

我怎样才能完成所需的双重排序?
更新
我编写了一个compare方法,它可以与qsort()一起工作,如下所示,但它不能从一个方面产生所需的结果。
我这样调用方法: qsort(nodes, num_of_nodes, sizeof(node), compare_pairs);
其中 compare_pairs()如下所示:
static int compare_pairs(node *n1, node *n2){

const node *na1 = n1;
const node *na2 = n2;

if(na1->p< na2->p) return -1;
if(na1->p> na2->p) return 1;

if(na1->t < na2->t) return -1;
if(na1->t > na2->t) return 1;

return 0;

问题
不受欢迎的行为从3点开始。步骤如下:
名单:[0.10 | 2][0.10 | 999][0.10 | 999][0.15 | 999][0.15 | 999][0.15 | 1][0.25 | 999]
应该是这样的:
名单:[0.10 | 2][0.10 | 999][0.10 | 999][0.15 | 1][0.15 | 999][0.15 | 999][0.25 | 999]
初始列表:
[0.25 | 999][0.15 | 999][0.15 | 999][0.10 | 999][0.10 | 999][0.05 | 999][0.05 | 999][0.05 | 999]
步骤:
正在擦除(最小)节点0.050000。。。
正在擦除(最小)节点0.050000。。。
正在创建(新)节点0.100000。。。
名单:[0.05 | 999][0.05 | 999][0.05 | 999][0.10 | 1][0.10 | 999][0.10 | 999][0.15 | 999][0.25 | 999]
步骤:
正在擦除(最小)节点0.050000。。。
正在擦除(最小)节点0.050000。。。
正在创建(新)节点0.100000。。。
名单:[0.05 | 999][0.10 | 1][0.10 | 2][0.10 | 999][0.10 | 999][0.15 | 999][0.15 | 999][0.25 | 999]
步骤:
正在擦除(最小)节点0.050000。。。
正在擦除(最小)节点0.100000。。。
正在创建(新)节点0.150000。。。
名单:[0.10 | 2][0.10 | 999][0.10 | 999][0.15 | 999][0.15 | 999][0.15 | 1][0.25 | 999]
步骤:
正在擦除(最小)节点0.100000。。。
正在擦除(最小)节点0.100000。。。
正在擦除(新)节点0.200000。。。
名单:[0.10 | 999][0.15 | 999][0.15 | 999][0.15 | 1][0.20 | 1][0.25 | 999]
步骤:
正在擦除(最小)节点0.100000。。。
擦除(最小)节点0.150000。。。
正在创建(新)节点0.250000。。。
名单:[0.15 | 999][0.15 | 1][0.20 | 1][0.25 | 1][0.25 | 999]
步骤:
擦除(最小)节点0.150000。。。
擦除(最小)节点0.150000。。。
正在擦除(新)节点0.300000。。。
名单:[0.20 | 1][0.25 | 1][0.25 | 999][0.30 | 1]
步骤:
正在擦除(最小)节点0.200000。。。
擦除(最小)节点0.250000。。。
正在擦除(新)节点0.450000。。。
名单:[0.25 | 999][0.30 | 1][0.45 | 1]
步骤:
擦除(最小)节点0.250000。。。
正在擦除(最小)节点0.300000。。。
正在创建(新)节点0.550000。。。
名单:[0.45 | 1][0.55 | 1]
步骤:
正在擦除(最小)节点0.450000。。。
正在擦除(最小)节点0.550000。。。
正在创建(新)节点1.000000。。。
清单:[1.00 | 1]
总体思路*
在每个步骤中,从列表中删除两个最小节点,并在列表中插入一个新节点插入的节点的t值比列表中的最大值大1,只是它没有将自己与t值999进行比较。如果列表中最大的t=999,则插入的t=999。
找到最好的t:
int max_t(node *nodes, int num, double p){
int max_t= 0;
int i;
for(i=0; i<num; i+=1){
if(nodes[i].p== p && nodes[i].t != 999){
if(nodes[i].t > max_t){
max_t = nodes[i].t;
}
}
}
return max_t;

主代码:
node *nodes = malloc(num_of_nodes*sizeof(node));
int i;
for(i=0; i<num_of_nodes; i+=1){
node n;
n.t = 999;
n.p = *(probabs+ i);
*(nodes+i) = n;
}

qsort(nodes, num_of_nodes, sizeof(node), compare_pairs);

while(num_of_nodes> 1){

printf("\n%d. STEP:\n", z);
z += 1;

// 2) Find two min nodes
node *min_n1 = malloc(sizeof(node));
node *min_n2 = malloc(sizeof(node));

*min_n1 = nodes[0];
printf("Erasing (min) node %lf...\n", min_n1->p);
nodes= erase_node(nodes, min_n1, num_of_nodes);
num_of_nodes -= 1;

*min_n2 = nodes[0];
printf("Erasing (min) node %lf...\n", min_n2->p);
nodes= erase_node(nodes, min_n2, num_of_nodes);
num_of_nodes-= 1;

// 3) Create new node, add it to the list
node *new:node = malloc(sizeof(node));
new_node->p= min_n1->p + min_n2->p;
double p = new->p;
int max_t = max_t(nodes, num_of_nodes, p);
new_node->t = max_t + 1;

printf("Creating (new) node %lf...\n", new_node->p);
node = add_node(nodes, new_node, num_of_nodes);
num_of_nodes += 1;

qsort(nodes, num_of_nodes, sizeof(node), compare_pairs);

printf("List: ");
int k;
for(k=0; k<num_of_nodes; k+=1){
printf("[%.2lf | %d] ", nodes[k].p, nodes[k].t);
}
printf("\n");

最佳答案

你的方法不必要地复杂不需要“排序两次”,只需要增强比较运算符。
另外,使用qsort()对C中的数组进行排序,这比滚动自己的排序要容易得多,而且可能还具有更好的性能。
基本上,你应该尝试填写这样一个函数的空白:

static int compare_pairs(const void *a, const void *b)
{
const node *na = a, *nb = b;

/* more code here */
}

实际上,当你说“我希望每个具有相同p的子数组都基于值t进行排序”时,你就有了解决方案。
这意味着比较函数的主体变成:
if(na->p < nb->p)
return -1;
if(na->p > nb->p)
return 1;
/* If we get this far, we know the p values are equal, so tie-break with t. */
if(na->t < nb->t)
return -1;
if(na->t > nb->t)
return 1;
return 0;

最后, please don't cast the return value of malloc() in C

关于c - 双重排序(将元素排序为2个不同的值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20049605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com