Java,字符串的LinkedList。按字母顺序插入

时间:2010-04-24 09:41:07

标签: java insert linked-list

我有一个简单的链表。该节点包含字符串(值)和int(计数)。

在插入时的链表中,我需要按字母顺序插入新节点。如果列表中有一个具有相同值的节点,那么我只需增加节点的计数。

我想我的方法真的搞砸了。

 public void addToList(Node node){
        //check if list is empty, if so insert at head
        if(count == 0 ){
            head = node;
            head.setNext(null);
            count++;
        }
        else{
            Node temp = head;
            for(int i=0; i<count; i++){
                //if value is greater, insert after
                if(node.getItem().getValue().compareTo(temp.getItem().getValue()) > 0){
                    node.setNext(temp.getNext());
                    temp.setNext(node);                   
                }
                //if value is equal just increment the counter
                else if(node.getItem().getValue().compareTo(temp.getItem().getValue()) == 0){
                    temp.getItem().setCount(temp.getItem().getCount() + 1);
                }
                //else insert before
                else{
                    node.setNext(temp);
                }
            }
        }      

    }

好的,这是插入我的所有字符串,但不按字母顺序排列。你看到有什么错误吗?

 public Node findIsertionPoint(Node head, Node node){
        if( head == null)
            return null;

        Node curr = head;
        while( curr != null){
            if( curr.getValue().compareTo(node.getValue()) == 0)
                return curr;
            else if( curr.getNext() == null || curr.getNext().getValue().compareTo(node.getValue()) > 0)
                return curr;
            else
                curr = curr.getNext();
        }

        return null;
    }

    public void insert(Node node){
        Node newNode = node;
        Node insertPoint = this.findIsertionPoint(this.head, node);
        if( insertPoint == null)
            this.head = newNode;
        else{
            if( insertPoint.getValue().compareTo(node.getValue()) == 0)
                insertPoint.getItem().incrementCount();
            else{
                newNode.setNext(insertPoint.getNext());
                insertPoint.setNext(newNode);
            }
        }
        count++;
    }

6 个答案:

答案 0 :(得分:3)

您的代码存在一些错误:

  • head之前/之前插入实际上需要在两种不同的场景中进行:
    • 如果列表为空,则head变为node
    • 如果列表不为空,但node小于第一个元素,则head也会变为node
      • 在任何一种情况下,node都链接到head之前指向的null或真实节点,head现在指向node
  • 如果您未在 head之前插入,则必须在某个节点之后插入。我们只需要找到这个地方的位置。有两种情况:
    • node.getValue() > temp.getValue()node.getValue() < temp.getNext().getValue()
    • node.getValue() > temp.getValue()temp.getNext() == null
      • 在任何一种情况下,都在nodetemp之间插入temp.getNext()

我建议在插入点搜索后将封装在自己的函数中。也就是说,给定列表和值,它需要返回一个节点。如果该节点具有与搜索值相同的值,则只需递增;否则,在之后插入。作为一种特殊情况,请返回null以指示 head之前插入点为


在伪代码中,它看起来像这样:

FUNCTION findInsertionPoint(Node head, V value) RETURNS Node
  // return null if value needs to be inserted before head
  IF head == null OR value < head.getValue()
     RETURN null;

  // otherwise, either return a node with the given value,
  // or return a node after which value should be inserted
  Node curr = head;
  REPEAT
     IF curr.value == value
        RETURN curr;
     ELSEIF curr.getNext() == null OR curr.getNext().getValue() > value
        RETURN curr;
     ELSE
        curr = curr.getNext();

PROCEDURE insert(V value) {
  Node newNode = NEW Node(value);
  Node insertPoint = findInsertionPoint(this.head, value);
  IF insertPoint == null // insert before head
     newNode.setNext(this.head);
     this.head = newNode;
  ELSE
     IF insertPoint.getValue() == value
        insertPoint.incrementCounter();
     ELSE // insert after insertPoint
        newNode.setNext(insertPoint.getNext());
        insertPoint.setNext(newNode);

更新:我看到您已将我的伪代码转换为Java,但出于某种原因,当headhead时,您忽略了处理IF head == null OR value < head.getValue() // ^^^^^^^^^^^^^^^^^^^^^^^^^^ 之前插入的代码不是空的。具体来说,你莫名其妙地省略了这一部分:

IF insertPoint == null 
   newNode.setNext(this.head); // <<<<<<<<<<<
   this.head = newNode;

和这部分:

"A"

这两者都是必需的;允许在head [ "B", "C", "D" ]之前插入{{1}}的内容。

您需要了解它们为什么重要,真的问自己为什么选择删除它们。向我们,向我自己解释,为什么你这样做;意识到错误并从中吸取教训。

答案 1 :(得分:1)

为了实现这一点,我不是从头开始自己的排序列表,而是实现Queue接口或扩展已经存在的PriorityQueue(或者可能更好地应用的任何其他排序集合)。我将Node类定义为Comparable接口的实现,或者使用Comparator实例实例化我的队列,并覆盖PriorityQueue add方法,仅当另一个对象尚未在队列中时才添加新节点,否则递增计数器。如果使用java&gt; 5.0进行类型安全,我会使用泛型来仅允许队列中的Node对象。

答案 2 :(得分:0)

我认为您希望使用Google Collections中的Multiset个实现之一。

Multiset的工作方式类似于Set,但允许重复(并计算它们!)。看看TreeMultiset

  

维护这个的多重集   按照其要素排序   无论是自然秩序还是自然秩序   显式比较器。

答案 3 :(得分:0)

如果没有看到完整的代码,就很难进行调试。 我认为问题在于你设置了

 Node temp = head; 
在循环之前

,但是在遍历列表到当前元素时需要重新分配temp。在这种情况下,您继续与head进行比较。

答案 4 :(得分:0)

  • 你在照顾这个案子的时候 list最初为空。您 还应该照顾特殊 新节点进入的情况 列表的开头。如果你的清单 是B->C->D,您正在插入A
  • node.next设置为null(如果尚未完成)的好处。所以 如果节点插入到 最后,我们将null作为下一个 最后一个节点。
  • 您需要更新要移动的临时文件 如果没有插入,则到下一个节点 可能。所以你错过了temp = temp.next;

答案 5 :(得分:0)

由于这是作业,我不打算给你任何源代码。我在代码中看到了一个大问题:

假设您的列表已有两个不同的项目,并且您正在插入一个新项目。在您的代码中,您正在检查node是否大于head,如果是,请立即将其插入,忽略列表中的其余项目。

您的代码执行此类操作。您可以填写一些遗漏的细节。

  1. 如果列表为空,请设置head = nodehead->next = NULL,然后您就完成了。

  2. 否则,如果node->value < head->value,请设置node->next = head, head = node

  3. 否则,如果node->value == head->valuehead->count++;

  4. 否则,请设置tmp = head。在tmp->next->value < node->value期间,设置tmp=tmp->next。 (检查空值!)。

  5. 如果tmp->next == NULL,(即您已到达列表末尾),请设置tmp->next = node,然后您就完成了。

  6. 否则,如果tmp->next->value == node->value,(即您到达了具有相同值的节点)tmp->next->count++

  7. 否则,如果node->next = tmp->next, tmp->next = node,则退出