C 如何从链表中删除重复的奇数?
要求/限制:C 如何从链表中删除重复的奇数?,c,data-structures,linked-list,C,Data Structures,Linked List,要求/限制: 仅删除重复项 留一份 列表最初未排序 如何在C中实现这一点? (非常感谢您提供算法和/或代码!)您可以先对列表进行排序,然后检查重复项,或者执行以下操作之一: for i from 0 to list.length-1 for j from i+1 to list.length-1 if list[i] == list[j] //delete one of them fi loop loop 您可以先对列表进
(非常感谢您提供算法和/或代码!)您可以先对列表进行排序,然后检查重复项,或者执行以下操作之一:
for i from 0 to list.length-1
for j from i+1 to list.length-1
if list[i] == list[j]
//delete one of them
fi
loop
loop
您可以先对列表进行排序,然后检查重复项,也可以执行以下操作之一:
for i from 0 to list.length-1
for j from i+1 to list.length-1
if list[i] == list[j]
//delete one of them
fi
loop
loop
这可能是最未优化的垃圾,但它可能会起作用。
在列表中迭代,每次转到下一个对象时都保持指向上一个对象的指针。在您的迭代循环中,对其进行迭代以检查是否存在重复项。如果存在重复,现在回到主迭代循环中,获取下一个对象。将指向下一个对象的“上一个对象”指针设置为刚检索到的对象,然后跳出循环并重新启动整个过程,直到没有重复的对象。这可能是最不优化的废话,但可能会起作用。
在列表中迭代,每次转到下一个对象时都保持指向上一个对象的指针。在您的迭代循环中,对其进行迭代以检查是否存在重复项。如果存在重复,现在回到主迭代循环中,获取下一个对象。将指向下一个对象的上一个对象指针设置为刚检索到的对象,然后跳出循环并重新启动整个过程,直到没有重复的对象。如果列表很长,您需要合理的性能,并且您可以分配额外的日志(n)内存,您可以在nlog(n)中排序使用qsort或合并排序: 然后可以删除n中的重复项(总数为:nlog(n)+n)
如果您的列表非常小,您可以按照jswolf19的建议执行,您将得到:n(n-1)/2最差。如果列表很长,您需要合理的性能,并且您可以分配额外的日志(n)内存,您可以使用qsort或merge sort在nlog(n)中排序: 然后可以删除n中的重复项(总数为:nlog(n)+n) 如果您的列表非常小,您可以按照jswolf19的建议执行,您将得到:n(n-1)/2最差的结果。我也可以
- 合并对列表进行排序,然后进行线性扫描以删除重复项
- 使用基于插入排序的算法,该算法在重新构建列表时已删除重复项
- 合并对列表进行排序,然后进行线性扫描以删除重复项
- 使用基于插入排序的算法,该算法在重新构建列表时已删除重复项
前者更快,后者更容易从头开始实现:只需从旧列表中弹出元素并将其插入新列表,然后扫描它,直到找到一个值更大(在这种情况下,您将元素插入列表)或值相等(在这种情况下,您将丢弃该元素)的元素,从而构建一个新列表.检测/删除重复项有几种不同的方法: 嵌套循环连接 按顺序取下一个值,然后扫描到列表末尾,查看该值是否再次出现。这是O(n2)——尽管我相信边界可以被证明更低但实际性能可能更好,因为只执行了从
i
到end
(而不是0
到end
)的扫描,并且可能会提前终止。除了一些变量外,这不需要额外的数据
(请参阅Christoph的回答,了解如何通过遍历链表和对新列表进行破坏性的“附加”来实现这一点——例如,嵌套循环不必“感觉”像嵌套循环。)
排序和筛选
对列表进行排序(可以修改mergesort以处理链接列表),然后检测重复值(它们现在将并排出现)。对于好的排序,这是O(n*lg(n))。排序阶段通常是/可能是破坏性的(例如,您有“一份”),但它已被修改;-)
扫描并保持查找
扫描列表,并在扫描列表时将值添加到查找中。如果查找已包含上述值,则存在重复!如果查找访问是O(1),则此方法可以是O(n)。通常使用“哈希/字典”或“集合”作为查找,但如果仅使用有限范围的整数,则数组将正常工作(例如,索引就是值)。这需要额外的存储空间,但不需要“额外的副本”——至少在文本读取中是这样
对于较小的n值,大O几乎毫无价值;-)
快乐编码。检测/删除重复项有几种不同的方法: 嵌套循环连接 按顺序取下一个值,然后扫描到列表末尾,查看该值是否再次出现。这是O(n2)——尽管我相信边界可以被证明更低但实际性能可能更好,因为只执行了从
i
到end
(而不是0
到end
)的扫描,并且可能会提前终止。除了一些变量外,这不需要额外的数据
(请参阅Christoph的回答,了解如何通过遍历链表和对新列表进行破坏性的“附加”来实现这一点——例如,嵌套循环不必“感觉”像嵌套循环。)
排序和筛选
对列表进行排序(可以修改mergesort以处理链接列表),然后检测重复值(它们现在将并排出现)。对于好的排序,这是O(n*lg(n))。排序阶段通常是/可能是破坏性的(例如,您有“一个副本”),但是