带链接列表的快速排序

时间:2012-02-24 00:59:46

标签: c sorting linked-list quicksort

我写下了以下程序,该程序使用快速排序算法对使用链接列表将多少整数放入命令行进行排序。我不仅得到关于混合声明的ISO C90错误,而且我的代码中某处存在内存泄漏,我不知道如何修复它。任何帮助将不胜感激!

#include <stdio.h>
#include "linked_list.h"
#include <stdlib.h>
#include "memcheck.h"
#include <string.h>
#include <assert.h>

node *quicksort(node *list);
int ListLength (node *list);

int main(int argc, char *argv[]) {
    if (argc == 1) {
    fprintf(stderr, "usage: %s [-q] number1 number2 ... \
    (must enter at least one argument)\n", argv[0]);
    exit(1);
    }
    node *list;
    node *sorted_list;
    int i;
    int intArg = 0; /* number of integer arguments */
    int print = 1;
    /* if -q is found anywhere then we are going 
     * to change the behavior of the program so that
     * it still sorts but does not print the result */
    for ( i = 1 ; i < argc; i++) {
        if (strcmp(argv[i], "-q") == 0) {
            print = 0;
        }
        else {
            list = create_node(atoi(argv[i]), list); /* memory allocation in the           create_node function */
            intArg++; }
    }

    if (intArg == 0) {
        fprintf(stderr, "usage: %s [-q] number1 number2 ...\
       (at least one of the input arguments must be an integer)\n", argv[0]); 
        exit(1); }
    sorted_list = quicksort(list);
    free_list(list);
    list = sorted_list;
    if (print == 1) {
        print_list(list); }
    print_memory_leaks();
    return 0; } 

/* This function sorts a linked list using the quicksort
 * algorithm */
node *quicksort(node *list) {
node *less=NULL, *more=NULL, *next, *temp=NULL, *end;
node *pivot = list;
if (ListLength(list) <= 1) {
    node *listCopy;
    listCopy = copy_list(list);
    return listCopy; }
else {
    next = list->next;
    list = next;
    /* split into two */
    temp = list;
    while(temp != NULL) {
        next = temp->next;
        if (temp->data < pivot->data) {
            temp->next = less;
            less = temp;
   }
        else {
            temp->next = more;
            more = temp;
  }
        temp = next;
  }
    less = quicksort(less);
    more = quicksort(more); }
   /* appending the results */
if (less != NULL) {
    end = less;
    while (end->next != NULL) {
        end = end->next;
  } 
pivot->next = more;
end->next = pivot;
return less; }
else {
    pivot->next = more;
return pivot; } } 
int ListLength (node *list) {
    node *temp = list;
    int i=0;
    while(temp!=NULL) {
        i++; 
        temp=temp->next; }
return i; }

2 个答案:

答案 0 :(得分:1)

main中,您释放一个节点,即列表的原始头部:

sorted_list = quicksort(list);
free_list(list);

但是你永远不会释放任何其他节点,尽管你复制节点。因此,从第一个开始保存的所有原始列表节点都浮动在无法访问的内存中。复制时为free,但free中不main,或者根本不复制(并释放main中的所有节点,但仅在您之后更长的需要他们)。

答案 1 :(得分:1)

好吧,您还没有发布free_list()create_node()的代码,这些代码是潜在内存泄漏的主要候选者,但我相信您的quicksort()代码存在内存泄漏:< / p>

    less = quicksort(less);
    more = quicksort(more); }

如果任一列表只有一个元素,那么这段代码:

if (ListLength(list) <= 1) {
    node *listCopy;
    listCopy = copy_list(list);
    return listCopy; }

返回一个元素的副本。通过在此处设置lessmore指针,您可能会丢失一个节点。

考虑清单:2 1 3

代码会将1添加到less列表,将3添加到more列表。然后它将在这两个单元素列表上执行quicksort(),返回列表的副本,并丢失指向原始lessmore列表的指针,从而导致内存泄漏两个节点。

巧合的是,最好将以上if语句的检查替换为:

if (list == NULL || list->next == NULL) {

这样可以避免遍历可能很长的列表,只是为了检查它是否只包含0或1个元素。