删除链接列表中的重复项

时间:2013-08-18 18:29:45

标签: c linked-list binary-search-tree duplicate-removal

我已经看过,编写并测试了一些逻辑以删除链表中的重复项。例如使用两个循环(O(n2)),或者排序和删除重复项虽然不能保留顺序 我只是想知道,如果我们提取链表的元素并开始创建二进制搜索树,使用二叉树算法中的标准重复检测来检测重复项,那么它是有效还是清晰。 这会比现有逻辑更有效,还是更糟?

4 个答案:

答案 0 :(得分:2)

您可以在O(n)时间内使用O(n)额外内存。这比BST方法更好:

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

答案 1 :(得分:1)

您的Binary Search tree(BST)替代方案会更快。让我们做一些分析:

  1. 实例化BST对象O(1)
  2. 使用链接列表N * O(log(N))中的每个节点填充BST 注意,作为插入操作的一部分,重复项将添加到树中。
  3. 从BST O(N)
  4. 重建链接列表

    删除重复项的BST方法在O(1)+O(N)+O(N*log(N)) = O(N*log(N))

    中运行

    它需要运行更多代码更多内存,但会删除quasi-linear time中的重复项。

答案 2 :(得分:0)

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

在c#中你有字典,在c ++中我认为你可以使用任何模板库

答案 3 :(得分:0)

这个解决方案解决了不允许额外内存并更改链接列表的问题。解决方案是在C#

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);
   }