我有一个链表,我想按名字对它们进行排序 (例如名称“Bx”,“Tx”,“Ax”将变为:“Ax”,“Bx”,“Tx”)... 如果节点右边的名字有一个“较小的名字”,我需要切换名字。
这就是我写的:
typedef struct data
{
char *name;
}data;
typedef struct Node
{
data NodeData;
struct Node *next;
struct Node *prev;
}Node;
void Sorting(Node *head)
{
Node *temp = head;
Node *temp2 = (Node*)malloc(sizeof(Node));
while (temp != NULL)
{
if (1 == (strcmp(temp -> NodeData.name, temp -> next -> NodeData.name)))
{
strcpy (temp2 -> NodeData.name, temp -> NodeData.name);
strcpy (temp -> NodeData.name, temp -> next -> NodeData.name);
strcpy (temp -> next -> NodeData.name, temp2 -> NodeData.name);
}
temp = temp -> next;
}
}
我得到一个运行时 - 我需要在节点名称(strcpy行)之间进行交换的部分错误: 访问冲突(分段错误)......
答案 0 :(得分:1)
我认为您不应该通过交换数据值对列表进行排序,而应该交换节点本身。请注意,这需要您将指针返回到列表的新第一个节点。
编辑:如果你是双重间接指针,那么将指针传递给列表的头部也是有效的。它也可以使代码更简单。
答案 1 :(得分:0)
temp2
此处为char*
char *temp2;
但Node
在这里
strcpy (temp2 -> NodeData.name, temp -> NodeData.name);
所以是的,在这一行上,你表现得好像temp2
是一个结构或联合,但事实并非如此。
答案 2 :(得分:0)
if (1 == (strcmp(temp -> NodeData.name, temp -> next -> NodeData.name))) {...}
执行此行时,无法保证temp-> next不为NULL。 如果它是NULL,则temp-> next-> NodeData.Name会非常痛苦。
另外,如前所述,测试strcmp()s对1的结果是不对的。 strcmp可以重新调整任何等于零的值,<零或>零。
另外,如前所述,strcpy()不对;字符串可以有不同的分配大小,或者可以存在于不可写的内存中(字符串常量)。交换指针就足够了。
更新:
void Sorting(Node *head)
{
Node *temp ;
/* since the compare dereferences temp->next you'll have to verify that it is not NULL */
for (temp = head; temp && temp->next; temp = temp->next)
{
if (strcmp(temp->NodeData.name, temp->next->NodeData.name) > 0 )
{
/* no need for a whole node, since you only copy a pointer */
char *cp;
cp = temp->NodeData.name;
temp->NodeData.name = temp->next->NodeData.name;
temp->next->NodeData.name = cp;
}
}
}
BTW:对链表进行冒泡排序真的很难看。链接列表更容易,并通过mergesort进行更精细的排序。