【问题标题】:Order a linked list alphabetically by name按名称字母顺序排列链表
【发布时间】:2013-11-04 20:39:57
【问题描述】:

我在按字母顺序组织链表时遇到问题。我正在从文本文件中读取名称并将它们存储到链接列表中。我遇到的问题是如何按字母顺序对它们进行排序。如果有人能指出我正确的方向,那就太棒了。这个想法是获取每个名称中前 3 个字母的值,并将它们与下一个名称中的前 3 个字母进行比较。但是我会在哪里比较这些字母呢?

这里是 LinkedListNode 类:

public class LinkedListNode
{

    private String data;
    private LinkedListNode next;


    public LinkedListNode(String data)
    {
        this.data = data;
        this.next = null;
    }

    public String getData()
    {
        return data;
    }

    public LinkedListNode getNext()
    {
        return next;
    }

    public void setNext(LinkedListNode n)
    {
        next = n;
    }
}

这里是带有main方法的LinkedList文件:

import java.io.*;
import java.util.Scanner;

public class LinkedList {

    public LinkedListNode head;
    String fname;

    public static void main(String[] args) throws FileNotFoundException{
            Scanner scan = new Scanner(new File("Names.txt"));
            LinkedList l = new LinkedList();    
            int i = 1;
            while(scan.hasNext()) {
                String s = scan.nextLine();
                l.insertBack(s);
                i++;
            }
            System.out.print(l.showList());
        }


    public LinkedList() {
        this.head = null;
    }

    public void insertBack(String data){

        if(head == null){
            head = new LinkedListNode(data);
        }else{
            LinkedListNode newNode = new LinkedListNode(data);
            LinkedListNode current = head;
            while(current.getNext() != null){
                current = current.getNext();
            }
            current.setNext(newNode);
        }
    }

    public String showList(){
        int i = 0, j;
        String retStr = "List nodes:\n";
        LinkedListNode current = head;
        while(current != null){
            i++;
            retStr += "Node " + i + ": " + current.getData() + "\n";
            current = current.getNext();

        }

        return retStr;
    }
}

【问题讨论】:

  • 如果您想始终保持List 排序,那么您可以将算法基于插入排序。如果您只想排序一次,则只需使用快速排序等标准算法。
  • 如果必须自己编写排序部分,那么我相信冒泡排序应该不难实现。
  • 在所有节点都构建完成后以及打印列表时,我会在 showList 函数中调用排序吗?
  • 您需要向我们提供更多信息。阅读我的评论。您是要始终对列表进行排序,还是要在最后进行排序?
  • 在这种情况下,您需要在添加元素时进行插入排序 - 请参阅 Cruncher 的答案以了解从哪里开始。

标签: java linked-list nodes


【解决方案1】:

给你一些伪代码:

OUTER:
for word in file
    node = head
    while node.next
        if word > node.word
             node.next
        else
             Node temp = new Node(word)
             temp.next = word.next
             node.next = temp
             continue OUTER
    node.next = new Node(word)

这是一个随用随插排序。每次插入后,文件都会被排序。或者你可以在读取所有数据后使用其他排序算法

如果是if word > node.word 这部分你遇到问题,String#compareTo 方法会很有用

【讨论】:

    【解决方案2】:

    尝试使用 Collections.sort(list)

    另外,为了比较,您可以使用 Comparable Interface 下的 compareTo 函数

    【讨论】:

    • OP的LinkedList真的是list吗?
    【解决方案3】:

    为了便于比较,您的节点应实现Comparable。基本的 Java 库倾向于依赖它来轻松排序。

    Comaprable 接口将要求您实现 compareTo(见下文)。

    public int <LinkedListNode> compareTo(LinkedListNode n){
      //Case insensitively compare the first 3 characters of the two nodes
      String myHead = data.substring(0,3).toLowerCase();
      String comparableHead = n.data.substring(0,3).toLowerCase();
    
      return (myHead.compareTo(comparableHead));
    
    }
    

    如果您使用像 ArrayList 这样的标准列表结构,Collections.sort(list) 将能够使用此方法对您的列表进行排序。

    这是一个基于插入排序的“插入”函数,用于您的运行时,使用这个可比较的。

    public void insert(String data){
        LinkedListNode newNode = new LinkedListNode(data);
        if(head == null){
            head = newNode;
        }else{
            LinkedListNode current = head;
            LinkedListNode prev;
    
            //This is missing some key edge cases, but it inserts properly in the general case.  You'll have to add to it to handle things like running off the list, or this needing to be inserted before the head.
            while(current.getNext() != null){
                if(current.compareTo(newNode)<0){
                  newNode.setNext(current);
                  prev.setNext(newNode);
                  break;
                }
                prev = current;
                current = current.getNext();
    
            }
    
        }
    }
    

    【讨论】:

    • 大概是 OP 的 LinkedList 可能不得不 implements List 这样做,不是吗?
    • 请注意,String 的默认比较器是 lexographic 排序,这意味着 'a' != 'A'。如果需要,您可以提供一个不区分大小写的新比较器
    • @BoristheSpider 你是绝对正确的,OP 必须利用现有的集合或实现接口来使用 Collections.sort。但是,实现 Comparable 可能对插入排序机制很有价值。 Comparator 只能比较前三个字符,因此无需在插入逻辑中使用 .substring。
    • 更新为使用代码 sn-p 来演示 Comparable 的用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多