簡體   English   中英

帶有鏈表C的冒泡排序

[英]Bubble sort with linked list C

我的排序算法在某些情況下似乎不起作用。 我正在一個雙向鏈表上(指向上一個和下一個的指針)。 我提交了我的結構和必要的定義。 我發現自己有一個無限循環,具有像這樣的特定情況。 我用strcmp()函數來排序。

#include "string.h"
#include "stdlib.h"
#include "stdio.h"

typedef struct s_file {
    char    *name;
    struct s_file     *next;
    struct s_file     *previous;
} t_file;

void swap_files(t_file *file, t_file *next)
{
    t_file *previous;

    previous = file->previous;
    if (previous)
        previous->next = next;
    file->next = next->next;
    file->previous = next;
    if (next->next)
        next->next->previous = file;
    next->next = file;
    next->previous = previous;
}

static t_file *sort_files(t_file *files)
{
    t_file *file;
    t_file *next;

    file = files;
    while ((next = file->next))
    {
        if (strcmp(file->name, next->name) > 0)
        {
            swap_files(file, next);
            if (!next->previous)
                files = next;
            file = files;
            continue;
        }
        file = file->next;
    }
    return (files);
}

void debug(t_file *files)
{
    while (files)
    {
        printf("=> %s\n", files->name);
        files = files->next;
    }
}

int main(void)
{
    t_file second;
    t_file first;
    t_file third;

    first.name = "Poire";
    first.previous = NULL;
    first.next = &second;

    second.name = "Banane";
    second.previous = &first;
    second.next = &third;

    third.name = "Fraise";
    third.previous = &second;
    third.next = NULL;

    first = *(sort_files(&first));
    debug(&first);
    return (0);
}

swap_files過於復雜。 只交換數據就足夠了:

void swap_files(t_file *file, t_file *next)
{
    char *tmp = file->name;
    file->name = next->name;
    next->name = tmp;
}

你猜怎么着? 它解決了這個問題。

在下面的評論中提到了這個解決方案的兩個問題,我想解決它們。 首先,如果有許多數據字段,此代碼可能效率較低,其次,您可能忘記了字段。

  1. 這不太可能是瓶頸,如果是,那么就應該處理它,而不是之前。 當只有一個字段時,此代碼更有效。 反對某種方法,因為如果情況不同會慢一點,這不是一個好的論據。

  2. 忘記一個領域是一個很好的例子。 我沒有異議。

以上兩者的解決方案是為數據創建第二個結構,如下所示:

struct data {
    char * name;
    int age;
    char * address;
    /* More fields */
}

struct s_file {
    struct data *data;
    struct s_file *next;
    struct s_file *previous;
}

你可以爭辯或反對這一點。 在某種程度上,它不會“感覺像C”,但另一方面,你可以很好地分離責任。

絕對應該first使用列表的新頭節點覆蓋,因為這樣做會導致列表被破壞。 只需定義一個指針來保存它:

    t_file *head = sort_files(&first);
    debug(head);

也不要使用"標准頭文件:

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

最后,即使使用這些修復,您的冒泡排序算法似乎也不正確:當您在filenext交換節點時,您應該回溯到前一個節點,以防next節點也小於前一個節點。

這是一個更正版本:

static t_file *sort_files(t_file *head) {
    t_file *file;
    t_file *next;

    file = head;
    while ((next = file->next) != NULL) {
        if (strcmp(file->name, next->name) > 0) {
            swap_files(file, next);    // swap the nodes linkage
            file = next;               // next is now before file
            if (file->previous) {
                file = file->previous; // backtrack to the previous node
            } else {
                head = file;           // save the new head of list
            }
        } else {
            file = file->next;
        }
    }
    return head;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM