我试图按字母顺序对链接列表进行排序,但看起来我的排序算法并不合适。我该如何对列表进行排序?
:
答案 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
因此,对于同一组数据,我们需要在冒泡排序算法中进行13次交换,而不是像alpha算法中那样使用8次。
(这种特殊的冒泡排序使用strcpy
函数与交换指针。)
我的结论是,呈现的“alpha排序”算法将始终比传统的冒泡排序更有效。这是因为我们立即开始排序,将元素连续添加到排序列表中。基本上我们可以将此算法视为改进的冒泡排序。
值得注意的是,不断增长的列表总是被排序,这对某些类型的应用程序非常有用。