2015-09-06 79 views
-2

下面我有一个简单的链接列表程序,它包含一个点和距离原点的距离。我的问题是,当调用排序函数时,它不能正确排序。我花了一段时间用gdb进行调试,但没有运气。我对C相对比较陌生,并且处理指针,所以如果有人能帮助我,我会非常感激!C链接列表气泡排序逻辑错误

我要发布输出的图像,但我没有足够的声誉看来,这样的输出看起来像下面是什么:

点:(3,1) - 距离:3.16228

点:(4,1) - 距离:4.12311

点:(1,1) - 距离:1.41421

点:(7,1) - 距离:7.07107

测试。 c文件:

#include <stdlib.h> 
#include <stdio.h> 
#include "point.h" 

typedef struct node 
{ 
    Point p; 
    double distance; 
    struct node *next; 
} node; 

void insertAtFront(node **start, Point *ip); 
void sort(node *start); 
void swap(node *a, node *b); 
void printList(node *start); 

int main(int argc, char **argv) 
{ 
    Point *insertPoint = malloc(sizeof(Point)); 
    node *head = NULL; 

    point_set(insertPoint,7.0,1.0); 
    insertAtFront(&head,insertPoint); 

    point_set(insertPoint,1.0,1.0); 
    insertAtFront(&head,insertPoint); 

    point_set(insertPoint,4.0,1.0); 
    insertAtFront(&head,insertPoint); 

    point_set(insertPoint,3.0,1.0); 
    insertAtFront(&head,insertPoint); 

    sort(head); 

    printList(head); 
} 

void insertAtFront(node **start, Point *ip) 
{ 
    node *node1 = (node*)malloc(sizeof(node)); 
    node1->p = *ip; 
    node1->next = *start; 
    *start = node1; 
} 

void sort(node *start) 
{ 
    Point *tp1 = malloc(sizeof(Point)); 
    Point *tp2 = malloc(sizeof(Point)); 
    int swapped; 
    node *node1; 
    node *node2 = NULL; 
    node *tempNode; 
    double d1; 
    double d2; 
    if(start == NULL) 
     return; 
    do 
    { 
     swapped = 0; 
     node1 = start; 
     *tp1 = node1->p;   
     tempNode = node1->next;  
     *tp2 = tempNode->p;  
     d1 = distanceFromOrigin(tp1); 
     d2 = distanceFromOrigin(tp2); 
     while(node1->next != node2) 
     { 
      if(d1 > d2) 
      { 
       swap(node1,node1->next); 
       swapped = 1; 
      } 
      node1 = node1->next; 
     } 
     node2 = node1; 
    } 
    while(swapped); 
} 

void swap(node *a, node *b) 
{ 
    Point *tp; 
    *tp = a->p; 
    a->p = b->p; 
    b->p = *tp; 
} 

void printList(node *start) 
{ 
    node *temp = start; 
    Point *tp = malloc(sizeof(Point)); 
    printf("\n"); 
    while(temp != NULL) 
    { 
     *tp = temp->p; 
     printf("Point: (%g,%g) - Distance: %g\n", point_getX(tp), point_getY(tp), distanceFromOrigin(tp)); 
     temp = temp->next; 
    } 
} 

point.c文件:

#include <stdio.h> 
#include "point.h" 
#include <math.h> 

void point_translate(Point *p, double x, double y) 
{ 
    point_set(p,(point_getX(p)+x),(point_getY(p)+y)); 
} 

double point_distance(const Point *p1, const Point *p2) 
{ 
    double temp1 = (point_getX(p1) - point_getX(p2)); 
    double temp2 = (point_getY(p1) - point_getY(p2)); 
    double temp3 = (temp1*temp1)+(temp2*temp2); 
    double dist = sqrt(temp3); 
    return dist; 
} 

double distanceFromOrigin(const Point *p1) 
{ 
    double x = point_getX(p1); 
    double y = point_getY(p1); 
    double temp = (x*x)+(y*y); 
    double dist = sqrt(temp); 
    return dist; 
} 

point.h文件:

#ifndef _POINT_H_ 
#define _POINT_H_ 

typedef struct Point 
{ 
    double x; 
    double y; 
} Point; 

void point_translate(Point *p, double x, double y); 
double point_distance(const Point *p1, const Point *p2); 
double distanceFromOrigin(const Point *p1); 

static inline double point_getX(const Point *p) 
{ 
    return p->x; 
} 
static inline double point_getY(const Point *p) 
{ 
    return p->y; 
} 
static inline Point *point_set(Point *p, double x, double y) 
{ 
    p->x = x; 
    p->y = y; 
    return p; 
} 

#endif 
+0

你介意张贴一个易于阅读你的问题的版本?显然你的问题是在排序函数中,所以你可以简单地使用一个简单的带有int链接列表的程序版本,这样我们就不需要你所有的代码来尝试和帮助你。另外从你的问题直接不清楚你想达到什么,但从代码我想你只是想按距离排序吗? – LBes

+0

是的,我只是将点添加到链接列表后按距离排序 – user3088903

回答

1

在你的“swap'功能的局部变量TP未初始化。你的编译器应该警告你这个。然后你无论如何访问它,这是未定义的行为...

+0

它编译和运行良好,所以我不知道这是一个问题 – user3088903

+0

现在你知道了。在做任何类型的C/C++编程时注意编译器警告是非常重要的。一定要打开它们。 – Cartan

+0

改变后的结果相同 – user3088903

0

当与node1-> next交换node1时,需要更改指向node1的前一个节点的下一个指针,或者可以交换node1和node1-> next,保持下一个指针不变。

如果你是交换指针,这里是什么样子交换前:

node0->next = node1, node1->next = node2, node2->next = node3 

和交换后:

node0->next = node2, node2->next = node1, node1->next = node3 

这只适用于相邻的节点。如果节点不相邻,然后交换前:

nodea->next = node1, node1->next = nodeb 
nodec->next = node2, node2->next = noded 

交换后

nodea->next = node2, node2->next = nodeb 
nodec->next = node1, node1->next = noded