【问题标题】:Double linked list sorting by ascending order双链表升序排序
【发布时间】:2020-03-26 18:26:19
【问题描述】:

我一直在为一个学校项目工作,遇到了这个问题。

我正在尝试使用 malloc 存储列表,但这段代码似乎不起作用。

column_t *sorted_insert(column_t *lst, char col3[MAX_SIZE], long int rep){

if (!lst || rep < lst->rep)
{
    column_t *new = (column_t*) malloc(sizeof(column_t));
    strcpy(new->col3, col3);
    new->rep = rep;
    new->next = lst;
    new->previous = NULL;
    lst = new;
    if (lst->next)
        lst->next->previous = new;
}else
{
    lst->next = sorted_insert(lst->next,col3,rep);
    lst->next->previous = lst;
}

return lst;
}

尝试调用函数:

sorted_insert(lst,"Test",0);
printf("%s",lst->col3);

而且没有输出。程序刚刚关闭。

从莫斯科更新@Vlad

column_t *sorted_insert(column_t *lst, char col3[MAX_SIZE], long int rep){

if (lst == NULL|| rep < lst->rep)
{
    column_t *new = malloc(sizeof(column_t));

    if (new != NULL)
    {
        strcpy(new->col3, col3);
        new->rep = rep;
        new->previous = NULL;
        new->next = lst;
        if (lst != NULL)
            lst->previous = new;

    }

    lst = new;
}else
{

    column_t *new = sorted_insert(lst->next, col3, rep);
    if (new != NULL)
    {
        lst->next = new;
        new->previous = lst;
    }

}

return lst;
}

将调用改为:

lst = sorted_insert(lst,tmp->col3,w);
display(lst);

输出:

列表的输出现在是正确的,但不是按升序排序的..

【问题讨论】:

  • 不应该是 if 中的 &amp;&amp; 而不是 ||
  • "这段代码似乎不起作用" 怎么回事?是什么让你这么想的?您尝试调试什么?请提供minimal reproducible example
  • 已更新。抱歉弄错了。
  • @Eraklon 如果列表为空或小于我认为的值..
  • rep的[目的]是什么?它没有改变。它是如何确定的?通常,您会根据strcmpcollst-&gt;col 之间插入,但您的代码似乎使用rep 作为排序标准。

标签: c sorting linked-list insert doubly-linked-list


【解决方案1】:

看来问题在于你是如何调用函数的。

调用应该是这样的

column_t *lst = NULL;
lst = sorted_insert(lst,"Test",0);

这是一个简化的演示程序,它使用您的函数 sorted_insert 进行了细微更改,并排除了字符数组类型的数据成员。

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

struct Node
{
    int data;
    struct Node *prev;
    struct Node *next;
};

struct Node * sorted_insert( struct Node *head, int data )
{
    if ( head == NULL || data < head->data )
    {
        struct Node *new_node = malloc( sizeof( struct Node ) );

        if ( new_node != NULL )
        {
            new_node->data = data;
            new_node->prev = NULL;
            new_node->next = head;
            if ( head != NULL ) head->prev = new_node;
        }

        head = new_node;
    }
    else
    {
        struct Node *new_node = sorted_insert( head->next, data );
        if ( new_node != NULL )
        {
            head->next = new_node;
            new_node->prev = head;
        }
    }

    return head;
}

void display( struct Node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }

    puts( "null" );
}

int main(void) 
{
    struct Node *head = NULL;

    const size_t N = 10;

    srand( ( unsigned int )time( NULL ) );

    for ( size_t i = 0; i < N; i++ )
    {
        head = sorted_insert( head, rand() % N );
        display( head );
    }

    return 0;
}

它的输出可能看起来像

8 -> null
3 -> 8 -> null
3 -> 8 -> 9 -> null
1 -> 3 -> 8 -> 9 -> null
1 -> 1 -> 3 -> 8 -> 9 -> null
1 -> 1 -> 3 -> 6 -> 8 -> 9 -> null
1 -> 1 -> 3 -> 3 -> 6 -> 8 -> 9 -> null
1 -> 1 -> 3 -> 3 -> 4 -> 6 -> 8 -> 9 -> null
1 -> 1 -> 3 -> 3 -> 4 -> 5 -> 6 -> 8 -> 9 -> null
1 -> 1 -> 3 -> 3 -> 4 -> 5 -> 6 -> 8 -> 9 -> 9 -> null

【讨论】:

  • 像你的一样更新了它,但输出不正确......我会在帖子上更新。
【解决方案2】:

警告:由于即使 Vlad 的回答您似乎仍然遇到一些问题,所以我提出了一个重构版本 [可能是您想要的,也可能不是您想要的]。 p>

我正在使用两个列表。将原始输入字符串附加到第一个列表,但如果它是现有列表条目的副本,则只是增加计数。

所以,现在我们有一个列表,其中包含每个唯一字符串的单个项目及其频率/重复计数。

然后,移动条目到第二个列表中,根据频率按插入排序。

所以,这里是代码。正如我在 cmets 中提到的,递归解决方案无法扩展,而且速度更慢。至少,这可以帮助您调整您的版本。 YMMV ...

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

#define MAX_SIZE    16

typedef struct column column_t;
struct column {
    column_t *next;
    column_t *prev;
    long rep;
    char col3[MAX_SIZE];
};

column_t *
newnode(char *col3)
{
    column_t *new = malloc(sizeof(column_t));

    strcpy(new->col3,col3);

    new->prev = NULL;
    new->next = NULL;

    new->rep = 1;

    return new;
}

// addnode -- add string to basic list
column_t *
addnode(column_t *head,char *col3)
{
    column_t *cur;
    column_t *prev;
    column_t *new;

    do {
        // add to empty list
        if (head == NULL) {
            new = newnode(col3);
            head = new;
            break;
        }

        // find matching node for string
        prev = NULL;
        for (cur = head;  cur != NULL;  cur = cur->next) {
            if (strcmp(cur->col3,col3) == 0)
                break;
            prev = cur;
        }

        // increment count on existing node
        if (cur != NULL) {
            cur->rep += 1;
            break;
        }

        // append to tail of list
        new = newnode(col3);
        prev->next = new;
        new->prev = prev;
    } while (0);

    return head;
}

column_t *
sorted_insert(column_t *head,column_t *new)
{
    column_t *cur;
    column_t *prev;

    do {
        new->next = NULL;
        new->prev = NULL;

        // add to empty list
        if (head == NULL) {
            head = new;
            break;
        }

        // find next higher node count
        prev = NULL;
        for (cur = head;  cur != NULL;  cur = cur->next) {
            if (cur->rep > new->rep)
                break;
            prev = cur;
        }

        // insert before a node that is higher
        if (cur != NULL) {
            prev = cur->prev;

            if (prev != NULL)
                prev->next = new;

            new->prev = prev;
            new->next = cur;

            // inserting before the head of the list
            if (cur == head)
                head = new;
            break;
        }

        // new node is higher than all -- append to tail of list
        new->prev = prev;
        if (prev != NULL)
            prev->next = new;
    } while (0);

    return head;
}

void
listprint(column_t *head,const char *tag)
{
    column_t *cur;

    for (cur = head;  cur != NULL;  cur = cur->next)
        printf("%s %s - %ld\n",tag,cur->col3,cur->rep);
}

int
main(void)
{
    column_t *orig = NULL;
    char *input[] = {
        "DA", "DA",
        "JL",
        "FF",
        "JD",
        "FF",
        "PQ", "QP",
        "QP", "QP", "QP",
        NULL
    };

    for (char **str = input;  *str != NULL;  ++str)
        orig = addnode(orig,*str);

    listprint(orig,"ORIG");

    column_t *sorted = NULL;
    column_t *next;
    for (;  orig != NULL;  orig = next) {
        next = orig->next;
        sorted = sorted_insert(sorted,orig);
    }

    listprint(sorted,"SORT");

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2022-01-09
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多