使用另一个列表排序链接列表

时间:2015-02-05 22:10:35

标签: c list sorting

所以我试图对整数的链表进行排序,但似乎无法找到正确的方法,我的想法是采取无序列表,从中找到最大值,并将其放入另一个列表。由于我不相信我可以从原始列表中删除节点而没有双重链接,因此我计划将列表1中的节点赋予零值,从而将其状态移除为最大值。因此我打算运行它一定次数,每次查找下一个最大值,直到列表1全部为0,列表2是列表1曾经是的有序版本。我已经创建了一个函数来执行此操作,但它似乎没有工作,虽然我找不到问题。

功能

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

struct num_node *create(struct num_node *list, int x){
    struct num_node *current;

    if (list == NULL){
        list = (struct num_node*)malloc(sizeof(struct num_node));
        list->num = x;
        list->next = NULL;
        return(list);
    }
    else{
        current = (struct num_node *)malloc(sizeof(struct num_node));
        current->num = x;
        current->next = list;
        return(current);
    }
} 

void print_nums(struct num_node *list) {

    struct num_node *current;
    for (current = list; current != NULL; current = current->next)
        printf("%d\t", current->num);

}

struct num_node *sort_nums(struct num_node *list1, struct num_node *list2){
    struct num_node *current;
    struct num_node *large = list1;

    for (int i = 0; i < 25; i++){
        for (current = list1; current != NULL; current = current->next){
            if (current->num > large->num){
                large = current;
            }
        }
        create(list2, large->num);
        large->num = 0;
        return(list2);
    }
}

int sum(struct num_node *list){
    int total = 0;
    struct num_node *current;
    for (current = list; current != NULL; current = current->next){
        total = total + current->num;
    }

    return total;
}

float average(struct num_node *list){
    float total = 0;
    float count = 0;
    struct num_node *current;
    for (current = list; current != NULL; current = current->next){
        total = total + current->num;
        count++;
    }
    return total / count;
}

主要

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

#include "functions.h"

int main(){
    struct num_node *head = NULL;
    struct num_node *new_head = NULL;

    srand(time(NULL));

        for (int i = 1; i <= 25; i++){
            int x = rand() % 100;
            head = create(head, x);
        }

        print_nums(head);

        sort_nums(head, new_head);

        printf("\n");
        printf("\n");
        print_nums(new_head);

        printf("\n");
        printf("\n");
        printf("The total of all numbers is: ");
        printf("\t%d\n", sum(new_head));

        printf("The average of the numbers is: ");
        printf("\t%.3f\n", average(new_head));


}

2 个答案:

答案 0 :(得分:1)

您提前退回sort_nums

struct num_node *sort_nums(struct num_node *list1, struct num_node *list2){
    struct num_node *current;
    struct num_node *large = list1;

    for (int i = 0; i < 25; i++){
        for (current = list1; current != NULL; current = current->next){
            if (current->num > large->num){
                large = current;
            }
        }
        create(list2, large->num);
        large->num = 0;
        return(list2);   // This just adds the largest item to list2
    }
}

你需要:

struct num_node *sort_nums(struct num_node *list1, struct num_node *list2){
    struct num_node *current;
    struct num_node *large = list1;

    for (int i = 0; i < 25; i++){
        for (current = list1; current != NULL; current = current->next){
            if (current->num > large->num){
                large = current;
            }
        }
        list2 = create(list2, large->num);
        large->num = 0;
    }
    return(list2);
}

此外,您没有在main中使用sort_nums的返回值。你有:

sort_nums(head, new_head);

你需要:

new_head = sort_nums(head, new_head);

简化create

由于您在create中将项目添加到列表中,因此可以简化为:

struct num_node *create(struct num_node *list, int x){
   struct num_node *current = malloc(sizeof(struct num_node));
   current->num = x;
   current->next = list;
   return(current);
} 

简化sort_nums

您还可以简化sort_nums。你不需要第二个论点。您可以使用:

struct num_node *sort_nums(struct num_node *list1){
   struct num_node *list2 = NULL;
   struct num_node *current;
   struct num_node *large = list1;
   int i;

   for (i = 0; i < 25; i++){
      for (current = list1; current != NULL; current = current->next){
         if (current->num > large->num){
            large = current;
         }
      }
      list2 = create(list2, large->num);
      large->num = 0;
   }
   return(list2);
}

当然,你必须改变在main中使用它的方式。

new_head = sort_nums(head);

答案 1 :(得分:0)

回到最初的想法,通过找到最大的节点来排序链表的示例代码,然后将其从原始列表中删除(原始列表的左边)并将该节点插入前面一个新的清单。请注意,面向合并的算法会快得多。

NODE * SortList(NODE * pList)
{
NODE * pNew = NULL;                     /* sorted list */
NODE **ppNode;                          /* ptr to ptr to node */
NODE **ppLargest;                       /* ptr to ptr to largest node */
NODE * pLargest;                        /* ptr to largest node */
    while(pList != NULL){               /* while list not empty */
        ppLargest = &pList;             /*  find largest node */
        ppNode = &((*ppLargest)->next);
        while(NULL != *ppNode){
            if((*ppNode)->data > (*ppLargest)->data)
                ppLargest = ppNode;
            ppNode = &((*ppNode)->next);
        }
        pLargest = *ppLargest;          /* move node to new */
        *ppLargest = pLargest->next;
        pLargest->next = pNew;
        pNew = pLargest;
    }    
    return(pNew);
}