在C中对链表进行排序时的无限循环

时间:2015-11-10 16:18:41

标签: c sorting linked-list

我是C编程新手,我必须对链表进行排序。该链表表示由用户输入创建的多项式。每个节点都有一个系数和一个功率。当我尝试对列表进行排序并将其返回到我打印它的主函数时,没有打印任何内容(我认为我的程序永远不会退出while循环)。

这里我创建了结构:

struct node
{
    int sunt;
    int dun;
    struct node* next;
};
typedef struct node* Poly;

这是我的代码,我对列表进行排序(head是我的初始列表名称):

struct node* poly = head;

struct node* temp;
int length = 0;

while (poly != NULL)
{
    length++;
    poly = poly->next;
}

poly = head;

while (length > 0)
{
    int i = 0;
    while ((poly != NULL) && (poly->next != NULL))
    {
        if (poly->dun > poly->next->dun)
        {
            temp = poly;
            poly = poly->next;
            poly->next = temp;
            if(i = 0)
            {
                head = poly;
            }
            i ++;
        }
        else
        {
            if(i = 0)
            {
                head = poly;
            }
            i ++;
        }
        poly = poly->next;
    }
    length --;
    poly = head;
}
return head;

这里是我在main函数中打印列表的地方(POLYmake函数是我创建和排序列表的地方):

poly1 = POLYmake();

while(poly1 != NULL)
{
    printf("%d %d \n", poly1->sunt, poly1->dun);
    poly1 = poly1->next;
}

我知道这很复杂,但我没有C经验,我希望你能帮助我。

5 个答案:

答案 0 :(得分:2)

此循环

while(length > 0)

永远都是如此,因为当你完成整个列表时,你只会减少一个。

另外,以下代码:

if(i = 0)
{
    head = poly;
}

应该是

if(i == 0)
{
    head = poly;
}

答案 1 :(得分:1)

...首先

if(i=0)

错误,因为它设置了我

我认为还有更多...你正在设置下一个节点 - >接下来是当前的,反之亦然,但是,你没有设置前一个节点 - >下一个或下一个节点 - >下一个节点,所以你很可能正在创建一个循环,即下一个节点都包含相同的指针。你需要绑定列表中的所有链接才能做到这一点,这很痛苦!

所以它应该是:

node* prev = null

[...] ensure you set the prev after each iteration

then
node* swap1 = poly;
node* swap2 = poly->next;

swap1->next = swap2->next; (which you'd have to null check for beforehand)
swap2->next = swap1;
prev->next = swap2;

但是:从概念上讲,你要交换整个链接只是交换一些数字。您可以在链接列表条目中嵌入一个结构指针(包含您感兴趣的ACTUAL值),然后交换它们而不是动态重组您的列表本身。

故事的寓意是,链表不是泡沫排序的最佳结构。

答案 2 :(得分:1)

我认为你打破你的链表并在内循环的第一个if分支

中形成一个循环
temp = poly; // (1) 
poly = poly->next; // (2)
poly->next = temp; // (3)

假设您有一个列表a - > b - > c - > ...然后在(1)之后输入if if then poly point to temp。在(2)之后poly将指向b。然后(3)语句将b的下一个指针分配给temp,即a。 这导致周期a - >。 b - > a - > b - > ...而且你永远不会达到c因此永远留在循环中。如果交换a和b,则应将a的下一个指针设置为c。

编辑:此外,还必须更新上一个节点(其下一个指针指向多边形)。为此,可以将前一个节点保存在单独的prev指针中,并且可以将prev->next设置为交换后两个中的第一个节点。

答案 3 :(得分:1)

让我们关注这个

temp = poly;
poly = poly->next;
poly->next = temp;

据推测,这个想法是交换列表中的两个元素。所以,让我们看一下列表

item1 -> item2 -> item3 -> item4 -> NULL

假设第2项的多边形点,你需要将它与item3交换。你要做的第一件事是将temp设置为poly,因此temp和poly都指向item2。

item1 -> item2 -> item3 -> item4 -> NULL
         poly
         temp

然后你将poly移动到指向poly-> next,即item3

item1 -> item2 -> item3 -> item4 -> NULL
                  poly
         temp

然后你设置poly的下一个指针指向temp,即item2

             V------------
item1 -> item2 -> item3 -|  item4 -> NULL
                  poly
         temp

请注意,现在没有任何内容指向item4。这是一次内存泄漏。另请注意,您的列表以循环结束,这意味着您永远不会遇到NULL,并且您永远不会退出内循环。

如何解决这个问题?

您会注意到poly之前的项目也需要更改其下一个指针,因此您需要一个前一个指针。我就是这样做的

// Set up the loop before you start
struct node* previous = NULL;
poly = head;
while (poly != NULL && poly->next != NULL)
{
    if (poly->dun > poly->next->dun)
    {
        if (previous == NULL)
        {
            head = poly->next;
        }
        else
        {
            previous->next = poly->next;
        }
        struct node* tail = poly->next->next;
        poly->next->next = poly;
        poly->next = tail;
    }
    previous = poly;
    poly = poly->next;
}

我认为这会奏效。 Haven没有测试过它。

答案 4 :(得分:0)

用实际代码显示一个简单的算法。

typedef struct node Node;
Node *bubbleSort(Node *head){
    if(head == NULL || head->next == NULL)//no need sort
        return head;

    Node anchor = { 0, 0, head }, *sentinel = NULL;
    while(1){
        Node *prev = &anchor, *curr = prev->next, *next = curr->next;
        if(next == sentinel)
            break;
        while(next != sentinel){
            Node *rest = next->next;
        //  prev --> curr --> next --> rest
            if(curr->dun > next->dun){
                prev->next = next;
                next->next = curr;
                curr->next = rest;

                prev = next;
                //curr = curr;
                next = curr->next;
            } else {
                prev = curr;
                curr = curr->next;
                next = curr->next;
            }
        }
        sentinel = curr;
    }

    return anchor.next;
}