| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2050 人关注过本帖
标题:关于qsort排序时,结构体内元素产生偏离了?
只看楼主 加入收藏
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
结帖率:93.75%
收藏
已结贴  问题点数:20 回复次数:6 
关于qsort排序时,结构体内元素产生偏离了?
问题主要是我声明了一个用来标记坐标的结构体变量,然后用qsort快排,快排是基于该节点与其父节点的距离长短。
然而出错了。通过在程序中插入printf显示,qsort 对结构体的各个变量的访问出了问题。
正确的输出应该是《x->x,x->y》《x->father->x,x->father->y》|《y->x,y->y》《y->father->x,y->father->y》
而程序输出的,,,《?,疑似父节点的y》《x->x,x->y》|《?,疑似父节点的y》《y->x,y->y》
图片附件: 游客没有浏览图片的权限,请 登录注册

源代码如下,主要也就关心一下main和Comp就行。。
程序代码:
#include <stdio.h>
#include<stdlib.h>

/*

 评测结果 时间     结果     得分     题目     编译器     用时(ms)     内存(MB)     用户
2016-04-17 18:19     正在评测     0     07-图5     gcc     无     无     569985011
测试点结果 测试点     结果     得分/满分     用时(ms)     内存(MB)     要点提示
测试点1     答案正确     15/15     17     1     sample1 多条最短路,同一点有多路,最近点无路,多连通
测试点2     答案正确     3/3     2     1     sample 2 聚集型,均离岸远
测试点3     答案正确     2/2     1     1     分散型,均跳不到,有在角上
测试点4     答案正确     3/3     2     1     有一只在岸上,有一只在岛上,不能算在内
测试点5     答案错误     0/6     1     1     最大N,sample1的复杂版,可选路径8条,后面要更新前面的最短路
测试点6     答案正确     1/1     2     1     最小N,一步跳到岸

*/
typedef struct node *Node;
struct node {
    int x,y;
    Node father;//记录他的father,出去以后在处理一遍。
};
typedef struct queue {
    Node Q[101];
    int Left,Right,Pause,Cen;
}*Queue;

int IsReached(Node,const int );
int CanReached(Node,Node,const float );
Node BFS(Node*,Queue,const int Lenth,int );

void Print(Node head) {
    if(head) {
        Print(head->father );
        if(head->x ==0&&head->y==0)return;
        printf("%d %d\n",head->x,head->y);
    }
}
Node SourceNode;
int Comp(const void*a,const void*b) {
    Node x=(Node)a;
    Node y=(Node)b;
    printf("&x=%d,&y=%d,",x,y);
    printf("<%d,%d><%d,%d>|<%d,%d><%d,%d>\n",x->x,x->y,x->father->x,x->father->y,y->x,y->y,y->father->x,y->father->y);
    int lenthx=((x->x)-(x->father->x))*((x->x)-(x->father->x))+((x->y)-(x->father->y))*((x->y)-(x->father->y));
    int lenthy=(y->x-y->father->x)*(y->x-y->father->x)+(y->y-y->father->y)*(y->y-y->father->y);
    return lenthx-lenthy;
}


int main() {
    int n;
    int lenth;
    Node L[101];

    scanf("%d%d",&n,&lenth);
        struct node Zero;
        Zero.x =0;Zero.y=0;Zero.father =NULL;
    printf("[%d,%d]",Zero.x ,Zero.y);   
    for(int i=0; i<n; i++) {
        L[i]=(Node)malloc(sizeof(struct node));
        scanf("%d%d",&L[i]->x,&L[i]->y);
        L[i]->father=&Zero;
        Node x=L[i];
        printf("(%d)",(x->x-x->father->x)*(x->x-x->father->x)+(x->y-x->father->y)*(x->y-x->father->y));
    }
    printf("\n|下面进入qsort函数|\n");
    qsort(L,n,sizeof(Node),Comp);
    for(int i=0;i<n;i++){
        printf("[%d,%d]",L[i]->x,L[i]->y);
    }
//---------------------
    if(lenth>=35) {//如果邦德会轻功~~~
        printf("1");
        return 0;
    }
//-----------------初始化队列
    struct queue Q;
    Q.Q[0]=&Zero;
    Q.Left =0;
    Q.Right =1;
    Q.Pause =0;
    Q.Cen =1;
//---------------------------

    Node head=BFS(L,&Q,lenth,n);
    if(!head)printf("0");
    else Print(head);
    return 0;
}
Node BFS(Node*L,Queue Q,const int Lenth,int n) {
    float IsFirstJump=7.5;//用来处理第一跳,本层遍历结束后就赋0.
    struct node None= {500,500};
    while(Q->Left <Q->Right) {
        for(int i=0; i<n; i++) {
            if(CanReached(Q->Q[Q->Left],L[i],Lenth+IsFirstJump)) {
                Node temp=L[i];
                L[i]=&None;
                temp->father=Q->Q[Q->Left];
                if(IsReached(temp,Lenth)) {
                    printf("%d\n",Q->Cen+1 );
                    return temp;
                }
                Q->Q[Q->Right++]=temp;
            }
        }

        if(Q->Left++==Q->Pause ) {
            qsort(&Q->Q[Q->Pause],Q->Right-Q->Pause,sizeof(Node),Comp);
            IsFirstJump=0;
            Q->Pause =Q->Right ;
            ++Q->Cen;
        }
    }
    return NULL;
}


int IsReached(Node L,const int lenth) {
    int flag=0;
    if(L->x >=50-lenth)flag=1;
    else if(L->x <=lenth-50)flag=1;
    else if(L->y >=50-lenth)flag=1;
    else if(L->y <=lenth-50)flag=1;
    return flag;
}
int CanReached(Node L,Node K,const float lenth) {

    int x,y;
    x=(L->x > K->x) ?(L->x)-(K->x):(K->x)-(L->x);
    y=(L->y > K->y) ?(L->y)-(K->y):(K->y)-(L->y);

    return lenth*lenth>=x*x+y*y?1:0;
}



[此贴子已经被作者于2016-4-18 14:37编辑过]

2016-04-18 13:55
alice_usnet
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:18
帖 子:370
专家分:2020
注 册:2016-3-7
收藏
得分:20 
楼主看一下qsort函数的原型大概就明白啦。

未佩好剑,转身便已是江湖
2016-04-18 16:33
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
回复 2楼 alice_usnet
能不能具体点讲。

qsort源码的原理我知道是快排,当数量小于一定的阙值是会调用选择排序。(好像是吧)

qosrt里面进行各种赋值/移动操作都是基于我传进去的sizeof(Node)和指针。
而compare(const void*,const void*)则是我自己写的。。。我实在是看不出来哪个参数传错了,毕竟当程序进入Compare函数时,L【0】和L[7]还是在正确的位置上,(因此我认为一开始我传给qsort的参数是没错的。)可这个时候,我对这个地址强制类型转换并输出就错了。不理解啊///

φ(゜▽゜*)♪
2016-04-18 18:13
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
回复 2楼 alice_usnet
我突然想起来,对结构体直接进行赋值,如果被赋值的那个本身带有指针,直接赋值据说不太好。

可我听说那也只是会令程序产生一些”野指针“,而已。

况且本案例中根本没来得及进行换位就已经发生错误了。。

φ(゜▽゜*)♪
2016-04-18 18:22
alice_usnet
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:18
帖 子:370
专家分:2020
注 册:2016-3-7
收藏
得分:0 
void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*))

看出问题了吗?qsort的第一个参数要求是void*,也就是一个普通数组,而你实际传给它的是指针数组,完全超出了qsort的理解范围之外。对库函数理解不全,乱用。

未佩好剑,转身便已是江湖
2016-04-18 18:25
alice_usnet
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:18
帖 子:370
专家分:2020
注 册:2016-3-7
收藏
得分:0 
之所以会出现10,20这种看似合理的数据,只不过是偶然“正确”地进行了二级解引用罢了。
L[i]->father=&Zero;

这行代码表明L[i]->father>x和L[i]->father>y都是为0的,更加说明实际的结果是错的。

未佩好剑,转身便已是江湖
2016-04-18 18:56
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
回复 5楼 alice_usnet
好的我明白了。。我传进去的确是是一个指针数组,但这不是错。
错在于我的sizeof()应该是sizeof(Node*)一个指向指针的指针
同时,在Comp里面也应该注意传递给我的参数其实是指向数组元素的指针,对于我的这种用法就该是指向指针的指针。
发图如下
图片附件: 游客没有浏览图片的权限,请 登录注册

谢谢你的提醒。

φ(゜▽゜*)♪
2016-04-18 19:07
快速回复:关于qsort排序时,结构体内元素产生偏离了?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019937 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved