添加到已排序的链表时如何避免段错误?

时间:2018-01-26 22:06:03

标签: c

我需要在添加新元素时创建一个新函数,它将它放在列表中,以便列表按排序顺序排列。我不确定我的实现是否正确,我的第一次尝试,我的小组成员,给出了分段错误。当我试图独自完成它时,它没有做任何事情。任何帮助将不胜感激。这是我的代码:

头文件:

typedef struct s{
        int value;
        struct s *next, *previous;
} node, *node_ptr;

c file:

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

void
print_list(node_ptr list) {
   // walk the list to print out the contents
   while (list) {
        printf("%d ",list->value);
        list = list->next;
   }
   printf("\n");
}

void delete_list(node_ptr list) {
   // walk the list to delete the elements
   node_ptr t;
   while (list) {
        t = list;
        list = list->next;
        free(t);
   }
}

node_ptr new_node(int value) {
   node_ptr t = (node_ptr)malloc(sizeof(node));
   t->value = value;
   t->next = t->previous = NULL;
   return t;
}

node_ptr add_to_back(node_ptr list, int value) {
   node_ptr t = list;
   node_ptr s = new_node(value);
   // special case: starting with an empty list
   if (t == NULL) return s;
   // at this point we know there is a least one element in
   // the list
   while (t->next != NULL)  // walk the list looking for the last element 
     t = t->next;
   // we are at the end so now we arrange the pointers
   t->next = s;
   s->previous = t;
   return list;
}

// my implementation after some research
node_ptr add_sorted(node_ptr list, int value) {
        node_ptr temp = list;
        node_ptr newNode;

        if(temp == NULL || temp->value < newNode->value)
        {
                newNode->next = temp;
                temp = newNode;
        }
        else
        {
                while(temp != NULL && temp->value < value)
                {
                        temp = temp->next;
                }
                newNode->next = temp->next;
                temp->next = newNode;
        }
        return newNode;
}

// second implementation with team
/*
node_ptr add_sorted2(node_ptr list, int value) {
        // This is the function you need to implement
        // when adding a new element place it in the list so that the list stays in sorted order.
        node_ptr temp = list;
        node_ptr n = new_node(value);

        if(temp == NULL)
        {
                temp->value = value;
                temp->next = NULL;
                return n;
        }
        else if(temp->next != NULL) {   
        while(temp->next != NULL) {

                 if(temp->value <= value) {
                        n->next = temp->next;
                        temp->next = n;
                        return n;               
                }
                else if(temp->value > value) {
                        temp = temp->next;
                }
                else {
                        temp->next = n;
                        return n;
                }
        }
        }
        return n; 
}
*/

int
main() {
   int in_val;
   node_ptr my_list = NULL;
   node_ptr sorted_list = NULL;
   scanf("%d",&in_val);
   while (in_val > 0) {  // going to read input until see 0 or negative
           my_list = add_to_back(my_list,in_val);
           sorted_list = add_sorted(sorted_list,in_val);
           scanf("%d",&in_val);
   }
   printf("List:\n");
   print_list(my_list);
   printf("Sorted List:\n");
   print_list(sorted_list);
   delete_list(my_list);
   delete_list(sorted_list);
}

1 个答案:

答案 0 :(得分:2)

分段错误对我很清楚,你在这里使用了一个未初始化的指针

if(temp == NULL || temp->value < newNode->value)
//                                  ^

任何其他newNode在任何地方取消引用,因为newNode永远不会在您的代码中初始化。

如果temp == NULL,您尚未初始化newNode,那么未定义的行为

在保留顺序的同时将节点添加到列表中很容易,

  1. 创建新节点
  2. 如果成功创建它,则遍历列表,直到下一个节点比新节点更小(取决于您希望的排序)。
  3. 找到它后,将当前节点next链接到新节点,next节点应该是新节点的next
  4. 就是这样。