我正在尝试自己学习数据结构和算法。我在C中编写了自己的双链表,现在我想编写一些算法来执行列表。交换列表项的首选方法是什么?交换内容或重新排列指向下一个和上一个列表项的指针是否更好?
答案 0 :(得分:9)
重新排列指针。交换数据项可能会产生副作用。特别是,您可能已经存储了对函数外部某个节点的引用,并且通常当您重新排列列表中节点的顺序时,您不希望人们持有对节点的引用突然发现该节点指向新数据。这是因为一般来说,节点的重要识别特征是它指向而不是在列表中的位置的数据。
答案 1 :(得分:0)
规范交换是通过指针重新排列完成的,没有副作用,当然更快:
void swap (node *a, node *b) {
node *tmp;
tmp = a;
a = b;
b = tmp;
}
答案 2 :(得分:0)
根据存储在链表的元素中的内容的类型,交换元素的实际内容会很棘手(例如,考虑不同长度字符串的链表),因此交换指针更容易它指向下一个和上一个列表项。
答案 3 :(得分:0)
取决于您如何分配内容。
如果您要存储指向内容的指针,那么切换内容并不是什么大问题。如果你有一个大结构属于你的节点,那么切换指针可能比复制整个内容更有效。
答案 4 :(得分:0)
我倾向于支持大多数人已经说过的话。一些背景可能会有所帮助:交换指针可以保证工作,而交换对象可能并不总是像它看起来那么简单。想想可能/将要创建的临时工具和异常(我的意思是一般而不是C ++语言特征方式)可能会发生并实际上使您的容器(列表)处于不良状态。在容器中查找不变量 - 这就是交换应该保持列表大小的完整性以及元素的完整和设计。
答案 5 :(得分:0)
交换内容还是重新排列指向下一个和上一个列表项的指针更好?
重新排列指针,因为交换节点的所有元素可能更昂贵。
就时间复杂度而言,交换两个指针是恒定的操作。
但是,如果要在两个节点之间交换所有元素,则需要访问所有元素,并与它们的对应对象交换它们,即O(f),其中f是结构的字段数代表节点拥有的数据(即节点拥有的数据数)。
换句话说,交换节点数据是线性操作,而交换两个指针是恒定的。
交换数据可能会有副作用,尤其是当您可能在函数外部某处存储了对节点的引用时,该引用已被接受的answer所涵盖,但我也想指出这一事实。