C 删除链接列表中的重复项

C 删除链接列表中的重复项,c,linked-list,binary-search-tree,duplicate-removal,C,Linked List,Binary Search Tree,Duplicate Removal,我已经看过、写过并测试了一些逻辑来删除链表中的重复项。e、 g.使用两个循环(O(n2)),或排序并删除重复项,尽管它不保持顺序。 我只是想知道,如果我们拉出链表的元素,并开始创建一个二叉搜索树,使用二叉树算法中的标准重复检测来检测重复项,这是有效的还是易读的。 这会比现有的逻辑更有效,还是更糟糕?最好的选择(fastern)是创建二叉树来查找副本,但需要更多的内存和代码 < C >你有字典,在C++中我认为有任何一个你可以使用 的库的模板>你的(BST)替代方法会更快。让我们做一些分析: 实例

我已经看过、写过并测试了一些逻辑来删除链表中的重复项。e、 g.使用两个循环
(O(n2))
,或排序并删除重复项,尽管它不保持顺序。
我只是想知道,如果我们拉出链表的元素,并开始创建一个二叉搜索树,使用二叉树算法中的标准重复检测来检测重复项,这是有效的还是易读的。
这会比现有的逻辑更有效,还是更糟糕?

最好的选择(fastern)是创建二叉树来查找副本,但需要更多的内存和代码

< C >你有字典,在C++中我认为有任何一个你可以使用

的库的模板>你的(BST)替代方法会更快。让我们做一些分析:

  • 实例化BST对象
    O(1)
  • 使用链表中的每个节点填充BST
    N*O(log(N))

    注意作为插入操作的一部分,不会将重复项添加到树中
  • 从BST
    O(N)
  • 删除重复项的BST方法运行于
    O(1)+O(N)+O(N*log(N))=
    O(N*log(N))

    它需要更多的代码和更多的内存来运行,但将删除中的重复项

    您可以在
    O(n)
    时间内使用
    O(n)
    附加内存来完成。这比BST方法更好:

  • 分配一个大小为n的布尔数组,将所有单元格初始化为false
  • 遍历链接列表:
    • 对于每个节点,将值散列/映射到数组中的唯一索引中
    • 将单元格值设置为true
  • 创建指向新列表的指针
  • 遍历原始列表:
    • 对于每个节点,将值散列/映射到数组中的唯一索引中
    • 如果单元格值为true,则将节点添加到新列表中
    • 将单元格值设置为false
  • 将旧列表头设置为新列表头并删除旧列表头

  • 此解决方案解决了不允许使用额外内存的问题,并在适当位置更改了链表。答案是C#


    那会很快
    O(n)
    。。为树占用额外内存。是否需要保留列表的原始顺序?保留原始顺序不是明确定义的要求。在列表中删除重复项后的原始顺序是什么
    1-5-6-4-5-8
    ?如何构建N个节点的BST不等同于O(NlogN)算法(插入的节点*搜索复杂度)?它仍然比O(N^2)好,但我不知道你是如何得到BST构建的O(N)@WhozCraig你是对的,我最初匆忙地写下了答案。我已经纠正了大O表示法。哈希,与映射相反,有。两个输入值将产生相同的输出值。此使用哈希的算法可能会删除唯一元素,因为它与另一个不同的元素共享哈希。@awashburn映射是哈希的私有情况。当然,这里我们讨论的是无碰撞hashing@icepack,同意创建临时数组。您可以在迭代旧列表时创建父节点,因此可以在第二次迭代中直接删除该节点,而无需另一个列表。
    public static void removeDuplicates(Node root) { 
            Node reset = root;
            Node current = null;
            Node previous = null;
            Hashtable h = new Hashtable();
            //initialize hash table to all 0 values
            while (root != null)
            {
                if(!h.ContainsKey(root.value))
                    h.Add(root.value, 0);
                root = root.next;
            }
    
            root = reset;
            ///count the number of times an element appears
            while (root != null)
            {
                h[root.value] = int.Parse(h[root.value].ToString()) + 1;
                root = root.next;
            }
    
            root = reset;
            previous = root;
            current = previous.next;            
            while (current != null) {
                if (int.Parse(h[current.value].ToString())>1)
                {
                    h[current.value] = int.Parse(h[current.value].ToString())-1;
                    previous.next = current.next;
                    current = current.next;
                }
                else {
                    previous = previous.next;
                    current = current.next;
                }
            }
    
          // print them for visibility purposes
            while (reset != null) {
                Console.Write(reset.value + "->");
                reset = reset.next;
            }
    
        }
    
     static void Main(string[] args)
        {
            Node one = new Node(1);
            Node two = new Node(1);
            Node three = new Node(1);
            Node four = new Node(2);
            Node five = new Node(2);
    
       RemoveDuplicates(one);
       }