簡體   English   中英

Java鏈表排序

[英]Java Linked List Sorting

因此,應用程序從外部文件中讀取了一堆字符串,每個字符串都位於單獨的一行中。

例如:

and
cake
here

它沒有以任何特定順序排列。 我需要閱讀這些字母並將它們放入鏈表中,最后對其進行排序。

我需要這樣做的幫助:

這是當前代碼:

import java.util.*;
import java.io.*;
public class LinkedList
{
  static File dataInpt;
  static Scanner inFile;
  public static void main(String[] args) throws IOException
  {
    dataInpt=new File("C:\\lldata.txt");
    inFile=new Scanner(dataInpt);
    Node first = insertInOrder();
    printList(first);
  }
  public static Node getNode(Object element)
  {
    Node temp=new Node();
    temp.value=element;
    temp.next=null;
    return temp;
  }
  public static void printList(Node head)
  {
    Node ptr; //not pointing anywhere
    for(ptr=head;ptr!=null;ptr=ptr.next)
      System.out.println(ptr.value);
    System.out.println();
  }
  public static Node insertInOrder()
  {
    Node first=getNode(inFile.next());
    Node current=first,previous=null;
    Node last=first;
    int count=0;
    while (inFile.hasNext())
    {
      if (previous!=null
          && ((String)current.value).compareTo((String)previous.value) > 0)
      {
        last.next=previous;
        previous=last;
      }
      if (previous!=null
          && ((String)current.value).compareTo((String)previous.value) < 0)
      {
        current.next=last;
        last=current;
      }
      previous=current;
      current=getNode(inFile.next());
    }
    return last;
  }
}

但這給“貓”帶來了無限循環。

這是數據文件:

Lol
Cake
Gel
Hi
Gee
Age
Rage
Tim
Where
And
Kite
Jam
Nickel
Cat
Ran
Jug
Here

好的,自學。 拆分閱讀和插入。 盡管舊代碼和新代碼都有14行代碼,但它使代碼更易於理解。

public static Node insertInOrder() {
    Node first = null;
    while (inFile.hasNext()) {
        String value = inFile.next().toString();
        first = insert(first, value);
    }
    return first;
}

/**
 * Insert in a sub-list, yielding a changed sub-list.
 * @param node the sub-list.
 * @param value
 * @return the new sub-list (the head node might have been changed).
 */
private static Node insert(Node node, String value) {
    if (node == null) { // End of list
        return getNode(value);
    }
    int comparison = node.value.compareTo(value);
    if (comparison >= 0) { // Or > 0 for stable sort.
        Node newNode = getNode(value); // Insert in front.
        newNode.next = node;
        return newNode;
    }
    node.next = insert(node.next, value); // Insert in the rest.
    return node;
}

這使用遞歸 (嵌套的“重新運行”),要求insertinsert 這就像循環,或將工作委派給克隆,或像數學歸納證明一樣工作。


迭代替代

也簡化了一點。

private static void Node insert(Node list, String value) {
    Node node = list;
    Node previous = null;
    for (;;) {
        if (node == null || node.value.compareTo(value) >= 0) {
            Node newNode = getNode(value);
            newNode.next = node;
            if (previous == null)
                list = newNode;
            else
                previous.next = newNode;
            break;
        }
        // Insert in the rest:
        previous = node;
        node = node.next;
    }
    return list;
}
public static Node insertInOrder()
{
    Node first=getNode(inFile.next());
    Node current=first,previous=null;
    Node last=first;
    int count=0;
    while (inFile.hasNext())
    {
        if (previous!=null
            && ((String)current.value).compareTo((String)previous.value) > 0)
        {
            last.next=previous;
            previous=last;
        }
        if (previous!=null
            && ((String)current.value).compareTo((String)previous.value) < 0)
        {
            current.next=last;
            last=current;
        }
        previous=current;
        current=getNode(inFile.next());
    }
    return last;
}

首先,您永遠不會對從文件中讀取的最后一行執行任何操作,因此永遠不會插入該行。 在重新鏈接next指針之前,您必須閱讀該行並創建新的Node

然后,如果lastprevious引用相同的Node並且current的數據大於previous

if (previous!=null
    && ((String)current.value).compareTo((String)previous.value) > 0)
{
    last.next=previous;
    previous=last;
}

您將last.next = last設置為列表。 從代碼(特別是缺少sort(Node)函數)看來,您似乎想對創建的列表進行排序。 但是,您只能相互比較每個新Node ,因此不會保持順序。

對於每個新節點,您都必須找到要在其后插入的節點,從列表的current.next掃描,然后修改current.next和前nextnext

在類似問題的相對簡單的代碼中,了解它的一個好方法是通過循環的幾個工作,檢查所有局部變量的值以查看代碼的效果。 如果代碼很簡單,您甚至可以手工完成。 如果手工操作太困難,則您的代碼可能太復雜了。 如果您不能遵循它,怎么知道您是否在做您打算做的事情。 例如,我可能是錯的,但這似乎是循環的每個迭代頂部的狀態。 它從第三次開始崩潰,到第四次,由於列表不連貫,您遇到了嚴重的問題。

1)last = first = Lol, current = previous = null
  Lol->null
2)last = first = previous = Lol, current = Cake
  Lol->Lol
3)first = Lol, last = Cake, previous = Cake, current = Gel 
  Cake->Lol->Lol 
4)first = Lol, last = Cake, previous = Cake, current = Hi
  Cake->Gel, Lol->Lol

老實說,如果我正在上這門課,我會認為正確的答案是:

List<String> list = new LinkedList<String>();
// read in lines and: list.add(word);
Collections.sort(list);

好的,我不記得確切的關於插入排序的學派理論,但是這里某種程度上是我認為的和您的代碼的混合:import java.io.File; 導入java.io.IOException; 導入java.util.Scanner;

public class LinkedList {
    public static class Node {
        public String value;
        public Node next;
    }

    static File dataInpt;
    static Scanner inFile;

    public static void main(String[] args) throws IOException {
        inFile = new Scanner("Lol\r\n" + "Cake\r\n" + "Gel\r\n" + "Hi\r\n" + "Gee\r\n" + "Age\r\n" + "Rage\r\n" + "Tim\r\n" + "Where\r\n"
                + "And\r\n" + "Kite\r\n" + "Jam\r\n" + "Nickel\r\n" + "Cat\r\n" + "Ran\r\n" + "Jug\r\n" + "Here");
        Node first = insertInOrder();
        printList(first);
    }

    public static Node getNode(String element) {
        Node temp = new Node();
        temp.value = element;
        temp.next = null;
        return temp;
    }

    public static void printList(Node head) {
        Node ptr; // not pointing anywhere
        for (ptr = head; ptr != null; ptr = ptr.next) {
            System.out.println(ptr.value);
        }
        System.out.println();
    }

    public static Node insertInOrder() {
        Node current = getNode(inFile.next());
        Node first = current, last = current;
        while (inFile.hasNext()) {
            if (first != null && current.value.compareTo(first.value) < 0) {
                current.next = first;
                first = current;
            } else if (last != null && current.value.compareTo(last.value) > 0) {
                last.next = current;
                last = current;
            } else {
                Node temp = first;
                while (current.value.compareTo(temp.value) < 0) {
                    temp = temp.next;
                }
                current.next = temp.next;
                temp.next = current;
            }
            current = getNode(inFile.next());
        }
        return first;
    }
}

它就像一種魅力。 當然,就性能和代碼重用而言,這遠非最佳。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM