繁体   English   中英

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

[英]Java, LinkedList of Strings. Insert in alphabetical order

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

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

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

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

您的代码有一些错误:

  • 实际上,需要在两种不同的情况下在head插入/插入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
      • 无论哪种情况,都将node插入temptemp.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,但由于某种原因你省略与之前插入涉及码head时, head不为空。 具体来说,您莫名其妙地省略了这一部分:

IF head == null OR value < head.getValue()
             // ^^^^^^^^^^^^^^^^^^^^^^^^^^

这部分:

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

两者都是必不可少的 ; 这就是允许在[ "B", "C", "D" ]head前面插入"A"的原因。

您需要了解它们为什么很重要,并真正问自己为什么选择删除它们。 向我们,对我,对自己解释为什么这么做; 意识到错误并从中学习。

为此,我将实现Queue接口或扩展已经存在的PriorityQueue(或可能更适用的任何其他排序集合),而不是从头开始开发自己的排序列表。 我将Node类定义为Comparable接口的实现,或者使用Comparator实例实例化我的队列,并重写PriorityQueue add方法以仅在队列中还没有另一个对象的情况下添加新的Node,否则增加计数器。 如果使用Java> 5.0进行类型安全,我将使用泛型来仅允许Queue中的Node对象。

我认为您想使用Google收藏夹中的一种Multiset实现。

多重集的工作原理类似于集合,但是允许重复(并计算重复!)。 看一下TreeMultiset

根据元素的自然顺序或显式Comparator保持其元素顺序的多重集。

没有完整的代码,很难进行调试。 我认为问题在于

 Node temp = head; 

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

  • 您已经处理了list最初为空的情况。 当新节点位于列表的开头时,您还应注意特殊情况。 如果您的列表是B->C->D并且您要插入A
  • 最好将node.next设置为null (如果尚未完成)。 这样,如果该节点插入到末尾,则最后一个节点的下一个null
  • 如果无法插入,则需要更新临时节点的温度。 因此,您缺少temp = temp.next;

由于这是家庭作业,因此我不会提供任何源代码。 我在代码中看到一个大问题:

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

您编写的代码是这样的。 您可以填写一些遗漏的详细信息。

  1. 如果list为空,则设置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并退出

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM