如何创建代码以排序方式将整数插入链表?

时间:2019-03-30 17:30:26

标签: c sorting linked-list

这是我任务的一部分。我必须在链接列表中放置一个数字。它必须是有序的,并且不允许重复。

我尝试了以下代码,但是我总是遇到分段错误。

int insertSortedLL(LinkedList *ll, int item)
{
    ListNode *current;
    int index=0;
    int res;

    if (ll == NULL || ll->head->item >= item) 
    {
        res=insertNode(ll,0,item);
        return 0;
    } 
    else
    { 
        /* Locate the node before the point of insertion */
        current = ll->head; 
        while (current->next!=NULL)
        { 
            if(current->next->item==item){
                return -1;
            }
            else if(current->next->item < item){
                current = current->next;
                index++;
            }
            else{
                break;
            }
        } 
        res=insertNode(ll,index,item);
        return index;
    } 
}

我希望它返回一个值,该值是它存储的数字的索引,但从未成功。另外,int insertNode是一个预先创建的函数,用于在选定的索引中插入数字,而ListNode是用于定义节点的。

1 个答案:

答案 0 :(得分:0)

您的代码中有几处错误。

  1. 即使作为参数传递的链表为NULL,您仍然会调用insertNode(ll,0,item)。如果链表为NULL,则将在100%的时间内导致分段错误。
    if (ll == NULL || ll->head->item >= item) 
    {
        res=insertNode(ll,0,item);
        return 0;
    } 
  1. 逻辑有点奇怪。似乎您不希望在列表中重复这些项,因为我根据此if语句(if(current->next->item==item))得出了结论,但是您没有为列表的第一项检查此条件。

  2. 使用功能insertNode会使代码效率降低。 insertNode将需要再次遍历列表,以将新项目放置在正确的位置。

编辑:这是一个肮脏的修复程序(与其他版本相比),以防止列表中出现重复项。

ListNode* make_node(int item){
    ListNode * new = malloc(sizeof(ListNode));
    new->item = item;
    new->next = NULL;
    return new;
}

int insertSortedLL(LinkedList *ll, int item){
    ListNode *current;
    ListNode *new;
    ListNode *tmp;
    int index=0;

    if(ll == NULL)
        return -1;

    //If the list is empty
    if(ll->head == NULL){
        ll->head = make_node(item);
    }

    if(ll->head->item == item)
        return -1;

    if(ll->head->item > item){
        new = make_node(item);
        new->next = ll->head;
        ll->head = new;
        return 0;
    }

    /* General case */
    current = ll->head; 
    while (current != NULL){
        if(current->next == NULL){
            current->next = make_node(item);
            return index;
        }else if (current->next->item == item){
            return -1;
        }else if (current->next->item < item){
            current = current->next;
            index++;
        }else{
            new = make_node(item);
            tmp = current->next;
            new->next = tmp;
            current->next = new;
            return index;
        }
    }
    return -1;
}

编辑:这是允许重复的版本。

#include <stdlib.h>

int insertSortedLL(LinkedList *ll, int item){
    ListNode *current;
    ListNode *new;
    ListNode *tmp;
    int index=0;

    if(ll == NULL)
        return -1;

    new = malloc(sizeof(ListNode));
    new->item = item;
    new->next = NULL;

    //If the list is empty or the first item of ll is greater
    if(ll->head == NULL || ll->head->item >= item){
        new->next = ll->head;
        ll->head = new;
        return 0;
    }

    /* General case */
    current = ll->head; 
    while (current != NULL){
        if(current->next == NULL){
            current->next = new;
            return index;
        }else if (current->next->item < item){
            current = current->next;
            index++;
        }else{
            tmp = current->next;
            new->next = tmp;
            current->next = new;
            return index;
        }
    }
    return -1;
}

valgrind是一个有用的工具,用于查找哪个代码段生成了Segmentation Fault消息(并且还有很多事情,例如查找内存泄漏等)。

使用-g -Wall -Wextra编译代码,不要忽略编译器警告消息(即使它们看起来无害),并使用valgrind运行程序。