Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在c中按字母顺序对链表排序_C_Sorting - Fatal编程技术网

如何在c中按字母顺序对链表排序

如何在c中按字母顺序对链表排序,c,sorting,C,Sorting,我试图按字母顺序对链表排序,但我的排序算法似乎没有。我如何对我的列表进行排序 typedef struct s_file { char *file_name; struct s_file *next; } t_file; void sort_alpha(t_file **begin_list) { t_file *list; char *tmp; list = *begin_list;

我试图按字母顺序对链表排序,但我的排序算法似乎没有。我如何对我的列表进行排序

typedef struct  s_file
{
    char        *file_name;
    struct      s_file *next;
}               t_file;

void    sort_alpha(t_file **begin_list)
{
    t_file  *list;
    char    *tmp;

    list = *begin_list;
    if (list)
    {
        while (list)
        {
            if (strcmp(list->file_name, list->next->file_name) < 0)
            {
                tmp = list->file_name;
                list->file_name = list->next->file_name;
                list->next->file_name = tmp;
            }
            list = list->next;
        }
    }
}
typedef结构文件
{
字符*文件名;
结构s_文件*下一步;
}t_文件;
无效排序字母(t文件**开始列表)
{
t_文件*列表;
char*tmp;
列表=*开始列表;
如果(列表)
{
while(列表)
{
如果(strcmp(列表->文件名,列表->下一步->文件名)<0)
{
tmp=列表->文件名;
列表->文件名=列表->下一步->文件名;
列表->下一步->文件名=tmp;
}
列表=列表->下一步;
}
}
}

在再次查看代码后,我对其进行了优化,以符合@TenTen-Peter的原始意图。不需要外环。正确完成排序:

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

// definition of the structure (global scope)
typedef struct  s_file
{
    char        *file_name;
    struct      s_file *next;
} t_file;

int static counter = 0;

void sort_alpha(t_file **begin_list)
{
  t_file    *list;
  char  *tmp;
  list = *begin_list;
  if (list)
    {
        while (list && list->next)
        {
            if (strcmp(list->file_name, list->next->file_name) > 0)
            {
                tmp = list->file_name;
                list->file_name = list->next->file_name;
                list->next->file_name = tmp;
                counter = counter + 1;
                printf("swap=%d\n",counter);
            }
        list = list->next;
        }
    }
}

int list_size(t_file **alst)
{
    int size = 0;
    t_file  *conductor;  // This will point to each node as it traverses the list
    conductor = *alst;      
    if ( conductor != 0 ) 
    {
        size = 1;
        while ( conductor->next != 0)
        {
            conductor = conductor->next;
            size = size + 1;
        }
     }
    return size;
}

void list_add(t_file **alst, t_file *newElement)
{
    printf("list_add->");
    if (newElement)
    {
         newElement->next = *alst;
         *alst = newElement;

        // Printing the added element
        printf("list_add:newElement=%s\n",(*alst)->file_name);

        // sorting:
        sort_alpha(alst); 
    }
    else
    {
        printf("NULL entry\n");
    }
}

t_file  *newEntry(char *file_name)
{
    t_file *file;
    file = (t_file *) malloc( sizeof(t_file) );
    printf("newEntry:file_name= %s\n",file_name);
    if (file)
    {
       file->file_name = file_name;
       file->next = NULL;
   }
   return (file);
}

// Untested
void read_dir(char *dir_name, t_file **begin_list)
{
    DIR *dir;   
    struct dirent *entry;
    dir = opendir(dir_name);
    if (!dir)
   {
        perror(dir_name);
        return;
   }
    while ((entry = readdir(dir)) != NULL){
        list_add(begin_list, newEntry(entry->d_name));
   }    
    closedir(dir);
}

int main(int ac, char **av)
{
    t_file *s,*iter,*e2,*e3,*e4,*e5,*e6,*e7;
    int j=0;
    
    printf("*Program Start*\n");        

    // Creating entries:
    s  = newEntry("dHea");
    e2 = newEntry("bbcx");
    e3 = newEntry("abcd");
    e4 = newEntry("cbcd");
    e5 = newEntry("cbad");
    e6 = newEntry("bbcd");
    e7 = newEntry("cbaa");

    // Adding entries to the list and sorting at the same time
    list_add(&s, e2);
    list_add(&s, e3);
    list_add(&s, e4);
    list_add(&s, e5);
    list_add(&s, e6);
    list_add(&s, e7);
    
    // It was done by:
    // read_dir(av[1], &s); // Untested
    
    // Print the sorted list
    iter = s;
    while (iter)
    {
        j++;
        printf("Printing sorted list: element %d = %s\n",j,iter->file_name);
        iter = iter->next;
    }

    printf("*Program End**\n");
    return 0;
}
代码如下:

编辑:因为有人可能担心上述算法的效率,所以我添加了一个交换计数器。它计算交换指针的需要发生了多少次。(请注意,不涉及副本)。 对于上述数据,该算法似乎非常有效。我们的7个元素列表只有8个交换

比较各种排序算法的排序时间:

冒泡排序[最佳:O(n),最差:O(n^2)]

选择排序[最佳/最差:O(N^2)]

插入排序[最佳:O(N),最差:O(N^2)]

快速排序[最佳:O(N lgn),平均:O(N lgn),最差:O(N^2)]

Heapsort[最佳/平均/最差:O(N lg N)]

计数排序[最佳/平均/最差:O(N)]

基数排序[最佳/平均/最差:O(N)]

源维基

对于同一组数据,让我们将上述算法与经典的气泡排序算法进行比较。 这是测试代码:

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

static int count = 0; 

int main(void) {

    char name[10][8], tname[10][8], temp[8];
    int i, j, n;

    printf("Enter the number of names\n");
    scanf("%d", &n);
    printf("Enter %d names\n", n);

    // reading names
    for (i = 0; i < n; i++)
    {
        scanf("%s", name[i]);
        strcpy(tname[i], name[i]);
    }

    // standard bubble sort  
    for (i = 0; i < n - 1 ; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (strcmp(name[i], name[j]) > 0)
            {
                strcpy(temp, name[i]);
                strcpy(name[i], name[j]);
                strcpy(name[j], temp);

                count = count + 1;
                printf("swap %d ", count);
            }
        }
    }

    // Print results:
    printf("\n----------------------------------------\n");
    printf("Input Names \tSorted names\n");
    printf("------------------------------------------\n");
    for (i = 0; i < n; i++)
    {
        printf("%s\t\t\t%s\n", tname[i], name[i]);
    }
    printf("------------------------------------------\n"); 
    return 0;
}
结果是:

Enter the number of names
Enter 7 names
swap 1 swap 2 swap 3 swap 4 swap 5 swap 6 swap 7 swap 8 swap 9 swap 10 swap 11 swap 12 swap 13 
----------------------------------------
Input Names     Sorted names
------------------------------------------
dHea            abcd
bbcx            bbcd
abcd            bbcx
cbcd            cbaa
cbad            cbad
bbcd            cbcd
cbaa            dHea

因此,对于同一组数据,我们需要在冒泡排序算法中进行13次交换,而不是像alpha算法那样进行8次交换

(这种特殊的冒泡排序使用
strcpy
函数和交换指针。)

我的结论是,提出的“alpha排序”算法将总是比经典的冒泡排序更有效。这是因为我们立即开始排序,连续地向排序列表添加元素。基本上,我们可以将此算法视为改进的冒泡排序


值得注意的是,不断增长的列表总是经过排序的,这对于某些类型的应用程序非常有用。

您需要将每个元素与其他元素进行比较,以找到它在排序列表中的位置。(是的,有更好的算法不需要O(n^2)比较)。阅读有关冒泡排序或选择排序的内容。从列表中创建一个指针数组,然后在数组上调用
qsort
,然后按排序顺序重新填充列表几乎更容易(除了小列表之外,任何操作都要快得多),代码所做的只是将最大的名称移动到列表中的最后一个节点。代码需要一个外部循环来重复该过程,直到没有检测到节点出现故障。从技术上讲,这不是对列表进行排序,而是对列表中节点的名称进行排序,而不是对节点(结构)进行排序。另一种方法是从空列表开始,然后从原始列表中删除节点,并按顺序将它们“插入”到最初的空列表中,当原始列表为空时,将生成一个排序列表。@silentman显示的“alpha排序”算法总是比
气泡排序
快,总是比
选择排序快得多。
其最佳时间复杂度优于O(n),最坏情况下总是小于O(n^2)。选择排序复杂度始终为O(n^2)。请参阅:@DavidC。当然,
qsort
的排名平均要比
冒泡排序快得多@rcgldr提供了完整的算法,不需要外循环。很难想象,如果您从
list\u add
调用sort,为什么不简单地按排序顺序添加节点。它只需要迭代,直到您在新节点之前找到节点并将其插入(例如插入
cbcd
,迭代
a、b、c、cb、cba,[插入此处]
。在开始时插入节点,然后每次插入都调用完整列表排序,随着列表大小的增加,效率会越来越低。如果从
list\u add
@DavidC.Rankin排序,则最好按排序顺序插入节点,因为它不是“完整排序”。我们不复制元素,只交换指针。你能发布你的
void list\u add(t\u file**alst,t\u file*newElement);
void sort\u alpha(t\u file**begin\u list)提案吗
这样我们就可以比较效率了?我很好奇它是否可以成本更低并且仍然有效。好吧,我知道代码的作用,我的观点是,当您可以简单地插入到插入点时,您可以将每个指针交换到排序顺序插入点。另一种方法是从
列表添加中删除
排序alpha
并在读取所有数据后调用它一次。编写时,您不需要将一个无序的节点插入为起始节点,然后将每个指针交换到添加的节点应该适合的位置——对于添加的每个节点。我不是说您的代码不工作,我只是说很难编写一种效率较低的方法@sg7感谢您的帮助,它可以工作,但很难对混合案例进行排序。@TenTenPeter我想您可能对以下内容感兴趣:
7 dHea bbcx abcd cbcd cbad bbcd cbaa
Enter the number of names
Enter 7 names
swap 1 swap 2 swap 3 swap 4 swap 5 swap 6 swap 7 swap 8 swap 9 swap 10 swap 11 swap 12 swap 13 
----------------------------------------
Input Names     Sorted names
------------------------------------------
dHea            abcd
bbcx            bbcd
abcd            bbcx
cbcd            cbaa
cbad            cbad
bbcd            cbcd
cbaa            dHea