簡體   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