在链接列表中以排序方式插入节点

时间:2018-05-25 15:50:15

标签: c sorting optimization linked-list

我试图按升序创建排序列表。我必须阅读一个包含每行一年的文件(所以我想从最早的日期到最近的日期订购)。

我尝试用我的代码完成的是:

  1. 列表项
  2. 从.csv文件的行中检索数据(年份);
  3. 遍历列表,直到找到包含数据的节点的位置;
  4. 重复直到文件结束;
  5. 打印;
  6. 每当我尝试运行它时,虚拟框开始滞后并且不做任何事情。 (即使我删除了打印功能)。

    我现在已经试图解决这个问题3天了,所以我非常绝望。

    这是我的代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    struct node {
    int data;
    int key;
    struct node *next;
    } node;
    
    
    struct node *head_countries = NULL;
    struct node *current = NULL;
    
    //display the list
    void printList() {
       struct node *ptr = head_countries;
       printf("\n[ ");
    
    
        //start from the beginning
        while(ptr != NULL) {
        printf("(%d,%d)",ptr->key,ptr->data);
        ptr = ptr->next;
    }
    
    printf(" ]");
    }
    
    //insert link at the first location
    struct node* insertFirst(int key, int data) {
        //create a link
        struct node *link = (struct node*) malloc(sizeof(struct node));
    
        link->key = key;
        link->data = data;
    
        //point it to old first node
        link->next = head_countries;
    
        //point first to new first node
        head_countries = link;
    
        return link;
        }
    
    void insertAfter(struct node* PrevNode, int key, int data)
    {
        struct node *NewNode = (struct node*) malloc(sizeof(struct node));
    
        if ( PrevNode == NULL )
        {
            printf("Erro 1");
            return;
        }
    
        NewNode->key = key;
        NewNode->data = data;
    
        NewNode->next = PrevNode->next;
        PrevNode->next = NewNode;
    
    }
    
    
    void CreateCountriesList()
    {
        char linha[150];
        char cabecalho[100];
        int key = 0, data = 0;
        int test[15] = {0};
    
        test[0] = 10;
        test[1] = 25;
        test[2] = 7;
        test[3] = 5;
        test[4] = 30;
        test[5] = 40;
        test[6] = 3;
        test[7] = 4;
        test[8] = 98;
        test[10] = 4;
        test[11] = 14;
        test[12] = 23;
        test[13] = 16;
        test[14] = 35;
        test[15] = 6;
    
        //dados_temp New_Entry;
    
        struct node* curr_head = NULL;
        struct node* curr = NULL;
    
        FILE *inputf;
        inputf = fopen("tempcountries_all.csv", "r");
    
    
        if (inputf == NULL)
        {
            printf("Nao da pa abrir o ficheiro");
            exit(EXIT_FAILURE);
        }
    
        fgets(cabecalho, 100, inputf);
    
        for (key = 0; key <  20 ; key++)
        {
            data = test[key]
    
        if ( head_countries == NULL || key == 2 )
        {
            insertFirst( key, data );
        }
    
        else
        {
            curr = head_countries;
            //insertAfter(curr, key, data);
            //printf("%d\n", curr->data);
            //curr = curr->next;
    
            while ( curr->next != NULL )
            {
                //printf("%d", key);
                if ( curr->data < data && curr->next->data > data )
                {
                    insertAfter(curr, key, data);
                }
    
                if ( data == curr->data )
                {
                    //insertAfter(curr, key, data);
                }
    
                curr = curr->next;
            }
        }
    
    
    }
    
    printList();
    
    fclose(inputf);
    }
    
    int main() {
    CreateCountriesList();
    return EXIT_SUCCESS;
    }
    

    是因为名单太大了吗?如果是这样,你怎么建议我继续这么大的名单?

    提前谢谢!

    编辑:从代码和未使用的函数中删除警告。

    编辑:添加测试。

2 个答案:

答案 0 :(得分:1)

您有几个问题,但最重要的问题似乎是围绕如何将数据插入列表:

    while ( curr->next != NULL )
    {
        //printf("%d", key);
        if ( curr->data < data && curr->next->data > data )
        {
            insertAfter(curr, key, data);
        }

        if ( data == curr->data )
        {
            //insertAfter(curr, key, data);
        }

        curr = curr->next;
    }

执行插入后,您不会从循环中断,所以请观察会发生什么:

  • 您要为要插入的数据找到合适的前导P。 curr将在那时指向P。
  • 在P。
  • 之后插入新节点N.
  • 您继续遍历列表。您考虑的下一个节点是P的后继节点,现在是N
  • N还符合数据的前任条件(data == N.data),因此您插入另一个新节点。而另一个。另一个......

这将无限期地继续,并且计算机确实可能在太长时间之前开始减速,因为它的物理和虚拟内存将被程序分配的所有节点加载。

答案 1 :(得分:0)

所以我猜你最大的问题就是制作这份清单......

这就是我如何制作这些功能。

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


typedef struct node {
int data;
int key;
struct node *next;
} node;


node *new_node(int key, int data)
{
    node * n =malloc(sizeof(node));
    if(!n)
    {
        fprintf(stderr,"malloc failed");
        exit(EXIT_FAILURE);
    }
    n->data = data;
    n->key = key;
    n->next = NULL;
}

node *insert_middle(node *next, int key, int data)
{
    node *new = new_node(key,data);
    new->next = next;
    return new;
}


node * insert_node(node *n, int key, int data)
{
    if(!n)
    {
        return new_node(key, data);
    }
    else if(n->data < data)
    {
        n->next = insert_node(n->next, key, data);
    }
    else
    {
        return insert_middle(n, key, data);
    }

}

int main()
{
    node *head=NULL;
    node *tmp = NULL;
    int i,j;
    for(i=0;i<10;i++)
    {
        scanf("%d",&j);
        tmp = insert_node(head, 0, j);
         //keep track of the head
        if(tmp!=head)
            head = tmp;
    }
    printf("====================");
    while(head)
    {
        printf("%d\n",head->data);
        head=head->next;
    }
    return 0;
}

我发现代码中的一些错误:

for (key = 0; key <  20 ; key++)
{
    //you never change the value of data
    data = test[0];

if ( head_countries == NULL || key == 2 )
{
     //you should place curr = insertFirst(key, data);
     //the way you have written the code nothing happens
    //inserFirst function just return the vale and you don't store it anywhere so you can not use it
    insertFirst( key, data );
}

else
{
    curr = head_countries;
    //after this line of code curr=NULL in first iteration 

     //curr->next will cause SIGSEGV since curr=NULL, so NULL->next is not possible
    while ( curr->next != NULL )
    {
        //printf("%d", key);


        if ( curr->data < data && curr->next->data > data )
        {
            insertAfter(curr, key, data);
        }
        if ( data == curr->data )
        {
            //insertAfter(curr, key, data);
        }

        curr = curr->next;
    }

太多错误......我想你应该重新开始。 如果你不理解我的例子只是评论,我将尽我所能解释