如何在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