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

时间:2016-06-11 02:47:34

标签: c sorting

我试图按字母顺序对链接列表进行排序,但看起来我的排序算法并不合适。我该如何对列表进行排序?

:

1 个答案:

答案 0 :(得分:0)

再次查看代码后,我对其进行了优化,以符合@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;
}

输出:

*Program Start*
newEntry:file_name= dHea
newEntry:file_name= bbcx
newEntry:file_name= abcd
newEntry:file_name= cbcd
newEntry:file_name= cbad
newEntry:file_name= bbcd
newEntry:file_name= cbaa
list_add->list_add:newElement=bbcx
list_add->list_add:newElement=abcd
list_add->list_add:newElement=cbcd
swap=1
swap=2
list_add->list_add:newElement=cbad
swap=3
swap=4
list_add->list_add:newElement=bbcd
swap=5
list_add->list_add:newElement=cbaa
swap=6
swap=7
swap=8
Printing sorted list: element 1 = abcd
Printing sorted list: element 2 = bbcd
Printing sorted list: element 3 = bbcx
Printing sorted list: element 4 = cbaa
Printing sorted list: element 5 = cbad
Printing sorted list: element 6 = cbcd
Printing sorted list: element 7 = dHea
*Program End**

代码在这里:code

编辑:由于人们可能对上述算法的效率感到担忧,我已经添加了一个交换计数器。它计算交换指针的次数发生的次数。 (请注意,不涉及复制)。 对于上述数据,该算法似乎非常有效。我们的7个元素列表中只有8个交换!

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

  

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

     

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

     

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

     

Quicksort [最佳:O(N lg N),平均值:O(N lg N),最差:O(N ^ 2)]

     

Heapsort [Best / Avg / Worst:O(N lg N)]

     

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

     

Radix sort [Best / Avg / Worst:O(N)]

来源维基Sorting

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

#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;
}

输入:

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

reference

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

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

我的结论是,呈现的“alpha排序”算法将始终比传统的冒泡排序更有效。这是因为我们立即开始排序,将元素连续添加到排序列表中。基本上我们可以将此算法视为改进的冒泡排序。

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