用链表实现C语言中的插入排序
我得做一个电话号码簿程序。程序应该从文件中读取名称和数字。我已成功创建包含此数据的链接列表。现在我想按字母顺序对它们进行排序。我该怎么做?这取决于你的目标 如果您想有效地执行此操作,请将指向每个元素的指针插入数组,然后使用类似(用链表实现C语言中的插入排序,c,sorting,insertion-sort,C,Sorting,Insertion Sort,我得做一个电话号码簿程序。程序应该从文件中读取名称和数字。我已成功创建包含此数据的链接列表。现在我想按字母顺序对它们进行排序。我该怎么做?这取决于你的目标 如果您想有效地执行此操作,请将指向每个元素的指针插入数组,然后使用类似(qsortin C)的算法按字母顺序对数组进行排序;最后,从排序的数组重新创建列表 另一方面,如果这是家庭作业,并且您必须按照文章标题的建议使用插入排序,则这是另一回事。创建链接列表后是否要对它们进行排序 对这样的数据进行排序的最佳方法可能是使用树,并在加载数据时创建已排
qsort
in C)的算法按字母顺序对数组进行排序;最后,从排序的数组重新创建列表
另一方面,如果这是家庭作业,并且您必须按照文章标题的建议使用插入排序,则这是另一回事。创建链接列表后是否要对它们进行排序 对这样的数据进行排序的最佳方法可能是使用树,并在加载数据时创建已排序的树。树数据结构的搜索速度也很快,尽管散列可能是最快的。请注意,strcmp不是排序或搜索的最快方式。您可以在搜索词中维护索引并对其进行编码,以便索引指向第一个不匹配的字符。那么你只需要比较一个字符。然而,我没有时间给出这方面的示例代码
typedef struct directory_entry_t
{
char *name;
char *number;
directory_entry_t *before;
directory_entry_t *after;
} directory_entry;
...
bool found;
while(!found)
{
int result = strcmp("name", node->name);
if(0 == result)
{
fprintf(stderr, "Duplicate entry for %s.\n", name);
}
else if(0 < result)
{
if(NULL == node->after)
{
/* Create a new node, populate it, and store a pointer to it at node->after. */
found = true;
}
else
{
node = node->after;
}
else
{
/* Like the above case, but for before. */
}
}
typedef结构目录\u条目\u t
{
字符*名称;
字符*数字;
之前的目录项;
之后的目录项;
}目录输入;
...
布尔发现;
而(!found)
{
int result=strcmp(“名称”,节点->名称);
如果(0==结果)
{
fprintf(stderr,“%s的重复条目。\n”,名称);
}
else if(0<结果)
{
if(NULL==节点->之后)
{
/*创建一个新节点,填充它,并将指向它的指针存储在node->after*/
发现=真;
}
其他的
{
节点=节点->之后;
}
其他的
{
/*像上面的例子,但之前*/
}
}
插入排序很慢,但如果要使用它,请查看
还有许多其他的,其中禁食(T&C适用)是O(NlogN)。我建议您选择或。对于排序来说,链表几乎是可以想象的最糟糕的数据结构。如果要插入,则必须对链表进行线性遍历。您确定问对了问题吗?对链表进行排序需要在线算法(即不依赖于快速随机访问的算法)如插入排序或基于堆栈的合并排序实现 如果要在已排序的列表中插入(少量)项,请使用插入排序。如果要对完整列表进行排序(或插入大量项),请使用合并排序 以下是这些算法的实现:
void insertionsort(node*head,node*tail)
void insertionsort(node *head,node *tail)
{
node *temp1=head,*temp2=temp1->next;
node *temp3;
while(temp1->next!=NULL)
{
(temp1==tail)
break;
temp2=temp1->next;
if(temp2->data<temp1->data)
{
int j;
j=temp2->data;
temp2->data=temp1->data;
temp1->data=j;
insertionsort(head,temp2);
}
temp1=temp1->next;
}
}
{
节点*temp1=head,*temp2=temp1->next;
节点*temp3;
while(temp1->next!=NULL)
{
(temp1==尾部)
打破
temp2=temp1->next;
如果(temp2->datadata)
{
int j;
j=temp2->data;
temp2->data=temp1->data;
temp1->data=j;
插入排序(头,temp2);
}
temp1=temp1->next;
}
}
quicksort需要随机访问轴选择,不能(有效地)与链接lists@Christoph如果您满足于第一个元素是轴心,则不会这样做……这将破坏已排序(或部分排序)的性能 lists@Christoph是的,你说得很对。但是对于一个可能是这样的家庭作业,只要你意识到这一点,那就不重要了。@Christoph同意,但我的观点是,你能想出一种更糟糕的排序数据结构吗?开玩笑的数组;如果你的对象很大,使用列表可以更快,因为你只需要重新排序-链接节点而不是复制数据;在实践中,您可能会创建一个指向对象的指针数组,然后对其进行排序,但有时对对象进行排序就不那么麻烦了list@Christoph:我倾向于使用引用对象的语言编程,因此实例数组在任何情况下都只是指针数组。我也是创建一个索引数组,然后用一些间接方法对这些索引进行排序。这允许您在不修改主数据的情况下进行排序。我必须承认我不知道mergesort,我打算阅读它,因为正如您所说,它适用于线性访问模式(与随机访问相反)。您应该查找(或找出答案)基于堆栈的变体:如果您天真地将数组的递归或迭代mergesort转换为链表,那么在细分列表时,您将不必要地遍历列表;Simon Tatham从wikipedia页面链接的代码使用迭代变体作为基础,在我的简单测试中,它实际上在列表上执行得最差。。。