【发布时间】:2017-09-23 07:21:26
【问题描述】:
我正在使用冒泡排序来更改节点位置。我知道如果节点 1 位于列表的开头,有几种情况需要注意。如果节点 2 在列表的末尾。如果 node1 在开头, node2 在结尾。所以我相信问题是当我交换邻居节点时,如 node1->next_ = node2;因为如果我进行常规交换,我最终会得到 node2->next_ = node2。
我想知道我是否走上了正轨,因为我尝试了类似于我写的东西并最终无限循环。我认为有些东西我不明白,就像我在某处丢失了指针一样。
我认为这是正确的,除非 2 个节点是链表中的邻居。
编辑明确的链接命名。恢复到原来的。
void swap(struct student_record_node** node1, struct student_record_node** node2)
{
struct student_record_node *p1, *x1, *n1, *p2,*x2,*n2, *temp;
p1 = (*node1)->prev_;
x1 = *node1;
n1 = (*node1)->next_;
p2 = (*node2)->prev_;
x2 = *node2;
n2 = (*node2)->next_;
/* swap next_ */
if (p1 == NULL && n2 == NULL)
{
/* step one swap nodes */
temp = *node1;
*node1 = *node2;
*node2 = temp;
/* step two swap node1 prev to be node2 prev */
(*node2)->prev_ = NULL;
/* step three swap node1 next to be node 2 next */
(*node2)->next_ = n1;
/* step four swap node1 next prev to be node2 next prev */
(*node2)->next_->prev_ = x2;
/* step 5 swap node2 next to be node1 next */
(*node1)->next_ = NULL;
/* step 6 swap node2 prev to be node1 prev */
(*node1)->prev_ = n2;
/* step 7 swap node2 prev next to be node1 prev next */
(*node1)->prev_->next_ = x1;
}
else if (p1 == NULL)
{
/* step one swap nodes */
temp = *node1;
*node1 = *node2;
*node2 = temp;
/* step two swap node1 prev to be node2 prev */
(*node2)->prev_ = NULL;
/* step three swap node1 next to be node 2 next */
(*node2)->next_ = n1;
/* step four swap node1 next prev to be node2 next prev */
(*node2)->next_->prev_ = x2;
/* step 5 swap node2 next to be node1 next */
(*node1)->next_ = n2;
/* step 6 swap node2 prev to be node1 prev */
(*node1)->prev_ = p2;
/* step 7 swap node2 prev next to be node1 prev next */
(*node1)->prev_->next_ = x1;
/* step 8 swap node2 next prev to be node1 next prev */
(*node1)->next_->prev_ = x1;
}
else if(n2 == NULL)
{
/* step one swap nodes */
temp = *node1;
*node1 = *node2;
*node2 = temp;
/* step two swap node1 prev to be node2 prev */
(*node2)->prev_ = p1;
/* step three swap node1 next to be node 2 next */
(*node2)->next_ = n1;
/* step four swap node1 next prev to be node2 next prev */
(*node2)->next_->prev_ = x2;
/* step 5 node1 prev next swapped with node2 prev next */
(*node2)->prev_->next_ = x2;
/* step 6 swap node2 next to be node1 next */
(*node1)->next_ = NULL;
/* step 7 swap node2 prev to be node1 prev */
(*node1)->prev_ = p2;
/* step 8 swap node2 prev next to be node1 prev next */
(*node1)->prev_->next_ = x1;
}
else
{
/* step one swap nodes */
temp = *node1;
*node1 = *node2;
*node2 = temp;
/* step two swap node1 prev to be node2 prev */
(*node2)->prev_ = p1;
/* step three swap node1 next to be node 2 next */
(*node2)->next_ = n1;
/* step four swap node1 next prev to be node2 next prev */
(*node2)->next_->prev_ = x2;
/* step 5 node1 prev next swapped with node2 prev next */
(*node2)->prev_->next_ = x2;
/* step 6 swap node2 next to be node1 next */
(*node1)->next_ = n2;
/* step 7 swap node2 prev to be node1 prev */
(*node1)->prev_ = p2;
/* step 8 swap node2 prev next to be node1 prev next */
(*node1)->prev_->next_ = x1;
/* step 9 swap node2 next prev to be node1 next prev */
(*node1)->next_->prev_ = x1;
}
/* swap surrounding */
}
【问题讨论】:
-
我将从使用有意义的变量名开始。通过认识到,例如,如果
(*node1)->prev_为 NULL,那么您绝对不允许访问(*node1)->prev_->next_(提示:您做)。当然,如果你使用调试器,你会准确找到崩溃的那一行,你就不需要在这里问了。 -
啊我忘了我做了那个改变。当我在这里发帖时,我试图让它更容易阅读。我想这是违反直觉的。是的,我不明白如何让 gdb 同时获取我的程序和 sample.txt 文件。
-
是的..你需要驯服你的调试器。没有它,您基本上无法开发软件。
-
如果您的数据不是超重的,那么通过交换数据而不是指针进行排序可能更容易。这有点像“作弊”,但如果它导致软件更简单,错误更少,那很好。另一种方法可能是将数据收集到一个数组中,对其进行排序,然后通过并行迭代数组和列表来覆盖列表。不过,这可能有点极端。
-
另一个选项是临时添加一个虚拟头尾节点到列表中。这样你就知道 all 你的指针是有效的。然后你只需在最后删除它们。进一步的简化是在对列表进行排序时只管理单个链接,然后进行最后一次设置所有
prev_指针。
标签: c sorting pointers struct doubly-linked-list